You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix(extractors): resolve inline object-literal dispatch tables on WASM
WASM's extractSubscriptCallInfo had no equivalent of native's RES-2
extract_dispatch_table_call, so ({a:fnA,b:fnB})[key]() classified as a
generic flagged computed-key sink while native resolved it to fnA/fnB
via the points-to wildcard solver — a genuine engine-parity gap.
Add extractDispatchTableCall, mirroring the native extractor: when a
subscript call's object is an object literal (optionally unwrapped
from a parenthesized expression) and the index is a bare identifier,
seed arrayElemBindings under a synthetic <dt_line_col> name and emit a
<dt_line_col>[*] call with dynamicKind 'dispatch-table' so the existing
pts wildcard resolution path (already used for array-literal dispatch)
picks it up identically on both engines. Threaded through both
extraction paths (dispatchQueryMatch for the WASM worker, handleCallExpr
for direct/test callers) per the two-path extractor architecture.
Adds 'dispatch-table' to the DynamicKind union and restores the
pts-javascript dispatch-table fixture, points-to unit tests, and a
query-vs-walk + cross-engine parity case that were dropped from a prior
merge without being ported to WASM.
Impact: 9 functions changed, 20 affected
Copy file name to clipboardExpand all lines: src/types.ts
+2-1Lines changed: 2 additions & 1 deletion
Original file line number
Diff line number
Diff line change
@@ -491,7 +491,8 @@ export type DynamicKind =
491
491
|'reflection'// .call/.apply/.bind / Reflect.* / callable-ref — resolved when target is in codebase; sink edge emitted if unresolved
492
492
|'eval'// eval() / new Function() — undecidable; always flagged
493
493
|'unresolved-dynamic'// any other detected dynamic pattern; flagged
494
-
|'value-ref';// bare identifier used as a value reference rather than a call site — object-literal property value (dispatch-table pattern, e.g. `{ resolve: someFn }`, #1771), assignment to a Lua global/builtin identifier (e.g. `require = tracedRequire`, #1776), or the right operand of an `instanceof` check (e.g. `err instanceof CodegraphError`, #1784) — resolved only against function/method/class-kind targets (class only relevant for the instanceof site); unresolved (e.g. plain data references) are dropped silently, NOT flagged
494
+
|'value-ref'// bare identifier used as a value reference rather than a call site — object-literal property value (dispatch-table pattern, e.g. `{ resolve: someFn }`, #1771), assignment to a Lua global/builtin identifier (e.g. `require = tracedRequire`, #1776), or the right operand of an `instanceof` check (e.g. `err instanceof CodegraphError`, #1784) — resolved only against function/method/class-kind targets (class only relevant for the instanceof site); unresolved (e.g. plain data references) are dropped silently, NOT flagged
495
+
|'dispatch-table';// inline object-literal subscript dispatch, e.g. `({a:fnA,b:fnB})[key]()` (#1897) — resolved via the points-to wildcard solver against synthetic `<dt_line_col>[*]` array-elem bindings seeded from each property's identifier value; never flagged (excluded from FLAG_ONLY_DYNAMIC_KINDS) so an unresolved table produces no sink edge, matching the named-array `[fn1,fn2][*]` dispatch pattern
495
496
496
497
/** A function/method call detected by an extractor. */
0 commit comments