Skip to content

feat(ladfile_builder): First look into a native Luau (.d.luau) LAD backend#546

Open
jonasdedden wants to merge 1 commit into
makspll:mainfrom
jonasdedden:feat/luau-lad-backend
Open

feat(ladfile_builder): First look into a native Luau (.d.luau) LAD backend#546
jonasdedden wants to merge 1 commit into
makspll:mainfrom
jonasdedden:feat/luau-lad-backend

Conversation

@jonasdedden

Copy link
Copy Markdown

This is a first proposal for generating Luau type definition files (corresponding issue: #545). Please let me know whether you like the general approach or not.

Tests

src/lib.rs carries module tests that parse a real registry dump (src/test_assets/bindings.lad.json) and assert both modes:

  • converts_general_surface — classes/fields/world/host globals present, and no Reg<T> leakage in the default output.
  • converts_branded_surfaceReg<T>, the generic get_component, and the …Type handle branding all present when opted in.
  • sanitizes_and_escapes — reserved-word handling.

Plus a well-formedness sweep asserting no Luau keyword is emitted as a bare field/method/param name. cargo test in this folder runs them against ladfile.

Luau grammar edges handled

  • reserved words can't be bare identifiers — quoted as ["end"] for fields, suffixed (end_) for methods/params/type names;
  • the unit type is () only in a return arrow — rendered as nil elsewhere;
  • BMS exposes every reflected type as a static accessor global — is_static separates those from real instance handles like world;
  • unknown/foreign types resolve to any (Luau treats it permissively), kept focused via focus_crates.

bevy_mod_scripting can dump its reflection registry to a LAD file and ships
post-processors for the Lua Language Server (`--- @class` .lua) and mdbook, but
no native Luau one — and luau-lsp cannot consume the LuaLS dialect. Luau users
(the `luau` runtime feature already exists) therefore have no way to type-check
their scripts from the registry.

Add that backend as a feature-gated module in ladfile_builder:

- `luau::lad_to_luau(&LadFile, &LuauBackendConfig) -> String`: the whole backend
  as a pure conversion, emitting `declare class … end` / `declare name: T`.
- `luau::LuauLadPlugin`: a `LadFilePlugin` processor, wired into
  `default_processors()` behind the new `luau_files` feature.

It needs no new dependencies (pure string generation over the `ladfile` types),
which is why it's a module here rather than a separate backend crate like the
LuaLS one. Handles Luau grammar edges: reserved words can't be bare identifiers
(quoted `["end"]` for fields, suffixed elsewhere), the unit type is `()` only in
a return arrow (`nil` otherwise), static accessor globals are excluded from real
instance handles, and unknown types resolve to `any`. `focus_crates` scopes which
crates' types get full classes so the output stays readable.

An opt-in `HandleBranding` config emits a `Reg<T>` phantom brand: it rewrites the
component getter to `get_component: <T>(…, reg: Reg<T>) -> T?` and brands each
host-registered `<Component><suffix>` registration global as `Reg<Component>`,
giving cast-free, statically-typed component access. Off by default since it
assumes a host naming convention.

Tested against `ladfile::EXAMPLE_LADFILE` (general surface, brand gating) and a
small crafted fixture (full brand path); generated output verified to load and
type-check under luau-lsp.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@semanticdiff-com

semanticdiff-com Bot commented Jun 11, 2026

Copy link
Copy Markdown

Review changes with  SemanticDiff

Changed Files
File Status
  crates/ladfile_builder/CHANGELOG.md Unsupported file format
  crates/ladfile_builder/Cargo.toml Unsupported file format
  crates/ladfile_builder/src/lib.rs  0% smaller
  crates/ladfile_builder/src/luau.rs  0% smaller
  crates/ladfile_builder/src/plugin.rs  0% smaller
  crates/ladfile_builder/src/test_assets/branded.lad.json  0% smaller

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant