feat(code-graph): add Lua language support to the v2 code indexer
**Difficulty:** L2 · **Labels:** `orbit::hackathon`, `orbit_hackathon::L2`, `orbit_hackathon::code-indexer`, `backend`, `type::feature` ## Outcome `.lua` files are indexed. Useful for Neovim plugin authors, game-dev mods (Roblox/Love2D), and embedded scripting. ## Background No existing backlog issue, but frequently requested. Tree-sitter grammar: [`tree-sitter-lua` 0.5.0](https://crates.io/crates/tree-sitter-lua). Lua is small with a tractable grammar — a good "second language to add" for a contributor learning the indexer. > **Validated:** crate compiles, `LANGUAGE` constant standard. ## Acceptance criteria - [ ] `tree-sitter-lua = { version = "0.5.0", optional = true }` + feature flag - [ ] `SupportLang::Lua` + `LanguageExt` arm - [ ] `Lua` row in `define_languages!`: `support_lang: Lua`, `extensions: ["lua"]`, `exclude: []`, `separator: "."`, `names: ["lua"]` - [ ] `LuaDsl` + `LuaRules` in `langs/generic/lua.rs` - [ ] Module registration + registry entry - [ ] Fixtures: definitions, requires (imports), cross-file calls + `yaml_test!` registrations - [ ] Probably set `file_scope() = true` since Lua scripts have no module declarations ## Scope rules to start with — verified against `tree-sitter-lua 0.5.0` Lua collapses everything into **one** node kind for function definitions: `function_declaration`. Disambiguate via children: - `function_declaration` with an `identifier` name child → top-level Function - `function_declaration` with a `local` keyword child → file-scoped Function - `function_declaration` with a `dot_index_expression` name (e.g. `M.greet`) → Function (or Method, depending on convention) - `function_declaration` with a `method_index_expression` name (e.g. `obj:method`) → Method, receiver = the LHS identifier - `function_call` whose `name` child is `identifier "require"` → `ImportRule` (Lua has no `import` keyword) The original draft's `function_statement` and `local_function` node kinds **do not exist** in tree-sitter-lua 0.5.0; everything is `function_declaration`. Variable bindings: - `variable_declaration > assignment_statement` — for `local x = ...` - `assignment_statement` (top-level) — for plain `x = ...` ## Notes - Lua has no class concept natively. Definitions-only (`Function` + `Method` only, no `Class`) is acceptable for v1. `setmetatable`-based OOP is out of scope. - `:` vs `.` method-call distinction matters for receiver inference — model it via the chain config's `field_access` entries (one for `dot_index_expression`, one for `method_index_expression`). - File scope: since Lua files are modules of their own with no `module` declaration, set `fn file_scope() -> bool { true }` so the file path forms the FQN root (mirrors C's behaviour). - Out of scope: dynamic dispatch through metatables, LuaJIT-specific syntax.
issue