Summary
Per ADR-002 (docs/architecture/decisions/002-dynamic-call-decisions.md — dynamic call taxonomy), a bracket-index call whose key is a literal string (obj["foo"]()) is Track A — resolvable — and other languages tag it dynamic: true, dynamicKind: 'computed-literal' so it's visible via codegraph roles --dynamic and the DynamicKind taxonomy, while still resolving to a normal edge. JavaScript's extractMemberExprCallInfo (src/extractors/javascript.ts) does exactly this for obj["method"]().
Lua's handle_lua_function_call (crates/codegraph-core/src/extractors/lua.rs, mirrored in src/extractors/lua.ts as of #1909) does not: for t["handler"]() it emits a plain, untagged Call { name: "handler", receiver: Some("t"), .. } with no dynamic/dynamicKind at all — the same shape as a static t.handler() call. The call still resolves correctly (same target), but it's invisible to codegraph roles --dynamic and any other dynamic_kind-based query, unlike the equivalent JS/other-language pattern.
Where this came from
Both crates/codegraph-core/src/extractors/lua.rs::handle_lua_function_call (added in f9e4e20d, #1656) and its WASM port in #1909 intentionally mirror each other's current (untagged) behavior for the literal-key case — so the two engines agree with each other, but neither matches the computed-literal convention used elsewhere in the codebase for the analogous pattern.
Suggested fix
Decide whether Lua's literal bracket-index call should be tagged dynamicKind: 'computed-literal' (matching JS's convention and ADR-002's Track A/B split) in both lua.rs and lua.ts, or whether plain resolution without tagging is intentional here (and if so, document why Lua differs from JS in ADR-002 or a code comment). Whichever direction is chosen, both engines must keep producing identical results.
Found incidentally while fixing #1909 (Lua WASM extractor missing eval/computed-key detection present in native) — not fixed inline since it's a distinct classification-design question, not a WASM/native parity bug.
Summary
Per ADR-002 (
docs/architecture/decisions/002-dynamic-call-decisions.md— dynamic call taxonomy), a bracket-index call whose key is a literal string (obj["foo"]()) is Track A — resolvable — and other languages tag itdynamic: true, dynamicKind: 'computed-literal'so it's visible viacodegraph roles --dynamicand theDynamicKindtaxonomy, while still resolving to a normal edge. JavaScript'sextractMemberExprCallInfo(src/extractors/javascript.ts) does exactly this forobj["method"]().Lua's
handle_lua_function_call(crates/codegraph-core/src/extractors/lua.rs, mirrored insrc/extractors/lua.tsas of #1909) does not: fort["handler"]()it emits a plain, untaggedCall { name: "handler", receiver: Some("t"), .. }with nodynamic/dynamicKindat all — the same shape as a statict.handler()call. The call still resolves correctly (same target), but it's invisible tocodegraph roles --dynamicand any otherdynamic_kind-based query, unlike the equivalent JS/other-language pattern.Where this came from
Both
crates/codegraph-core/src/extractors/lua.rs::handle_lua_function_call(added inf9e4e20d, #1656) and its WASM port in #1909 intentionally mirror each other's current (untagged) behavior for the literal-key case — so the two engines agree with each other, but neither matches thecomputed-literalconvention used elsewhere in the codebase for the analogous pattern.Suggested fix
Decide whether Lua's literal bracket-index call should be tagged
dynamicKind: 'computed-literal'(matching JS's convention and ADR-002's Track A/B split) in bothlua.rsandlua.ts, or whether plain resolution without tagging is intentional here (and if so, document why Lua differs from JS in ADR-002 or a code comment). Whichever direction is chosen, both engines must keep producing identical results.Found incidentally while fixing #1909 (Lua WASM extractor missing eval/computed-key detection present in native) — not fixed inline since it's a distinct classification-design question, not a WASM/native parity bug.