fix(lua): port eval/computed-key dynamic-call detection to WASM extractor#2043
Conversation
…ctor The native Rust Lua extractor already detected load()/loadstring()/dofile() as eval and t[k]() bracket-index calls as computed-key (or resolved directly for a string-literal key), but src/extractors/lua.ts never had the equivalent logic despite a prior commit claiming parity — so `--engine wasm` and `--engine native` diverged on any Lua file using these patterns. Ports handleLuaFunctionCall's eval/bracket-index handling from lua.rs into lua.ts, matching the Call shape (dynamic/dynamicKind/keyExpr/receiver) used by the other TS extractors. No changes to build-edges.ts/incremental.ts are needed since eval/computed-key are already generic FLAG_ONLY_DYNAMIC_KINDS. Also adds Rust unit test coverage for this logic, which had none. Impact: 1 functions changed, 2 affected
| if (ident === 'load' || ident === 'loadstring' || ident === 'dofile') { | ||
| ctx.calls.push({ | ||
| name: '<dynamic:eval>', | ||
| line: node.startPosition.row + 1, | ||
| dynamic: true, | ||
| dynamicKind: 'eval', | ||
| }); | ||
| return; | ||
| } |
There was a problem hiding this comment.
loadfile omitted from eval detection
loadfile is listed in LUA_BUILTIN_GLOBALS on line 30 alongside load, loadstring, and dofile, and it performs the same dynamic-code-loading operation (it compiles a Lua file and returns a chunk function). The eval guard currently covers load, loadstring, and dofile but not loadfile, so loadfile("script.lua")() — and any call graph that passes through a loadfile result — will not be flagged as a dynamic eval site. This mirrors the native Rust extractor's equivalent omission, so no parity divergence is introduced here, but the shared gap is worth addressing in both extractors.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Codegraph Impact Analysis1 functions changed → 2 callers affected across 1 files
|
Summary
The native Rust Lua extractor (
crates/codegraph-core/src/extractors/lua.rs,handle_lua_function_call) already detects two dynamic-call patterns that the WASM/TS Lua extractor (src/extractors/lua.ts,handleLuaFunctionCall) never implemented, despite a prior commit (f9e4e20d, #1656) claiming to mirror it:load(...)/loadstring(...)/dofile(...)— dynamic code execution, classifieddynamicKind: 'eval'.t[k]()(bracket_index_expressioncall target) — classifieddynamicKind: 'computed-key', or resolved directly (as a plain call) whenkis a string literal.This ports both patterns into
src/extractors/lua.ts'shandleLuaFunctionCall, matching theCallshape (dynamic/dynamicKind/keyExpr/receiver) established by the other TS extractors (e.g.src/extractors/javascript.ts).childForFieldName('field')(confirmed against both the npm@tree-sitter-grammars/tree-sitter-luagrammar used by WASM and thetree-sitter-luacrate used by native — both declarefield('field', $.expression)forbracket_index_expression), which is simpler than native's manual child-scan for the same node and produces identical results.build-edges.ts/incremental.ts/build_edges.rs:evalandcomputed-keyare already generic entries inFLAG_ONLY_DYNAMIC_KINDS, handled uniformly across all languages.lua.rs, which had none since it was introduced in feat(dynamic-calls): Phase 6 Rust parity — add GetMethod/Invoke/apply detection to Rust extractors (C#, Swift, Elixir, Lua) #1656.Verification
npx vitest run tests/parsers/lua.test.ts— 21/21 passed (7 new tests for eval/computed-key)cargo test --package codegraph-core --lib lua::— 16/16 passed (6 new tests mirroring the TS coverage)npm test— full suite: 253 files / 4013 tests passed, 0 failednpm run lint— clean (no new issues)napi build --platform --release), codesigned, and verified directly: built a small Lua fixture exercising all patterns (load,loadstring,dofile,t["handler"](),t['handler'](),t[k](),handlers[eventName .. "Handler"]()) and confirmed--engine wasmand--engine nativenow produce byte-identicalcodegraph roles --dynamic --jsonoutput (1eval+ 1computed-keysink edge each) and identicalfn-impactresolution for the literal-key case.Filed #2042 (Lua's literal-key bracket-index call resolves silently instead of tagging
computed-literallike JS does for the equivalent pattern) as a separate out-of-scope design question — both engines already agree with each other on this behavior, so it isn't a parity bug, just a possible taxonomy gap worth deciding on its own.Closes #1909
Stacked on #1907 (base branch
fix/issue-1907-scripts-token-benchmark-ts-perf-dynamic) — only the Lua extractor/test diff is this issue's change.