Skip to content

issue-2088 plan: for...in enumeration and direct TABLE[computedExpr]() calls get no correlated or computed-dispatch evidence #2619

Description

@carlos-alm

Found during round-6 review of #2612 (issue-2088's implementation plan).

Problem

docs/plans/issue-2088.md's escape-analysis design (WU-2) tracks a reference in for (const r of T) (the of variant only) as a safe position, because forOfBindings models it in the points-to solver. The in variant of the same for_in_statement node type enumerates KEYS, not values:

for (const k in T) T[k]();

Here, T[k]() uses a dynamic key (k, the loop variable) — the call has no statically-known property name, so:

  • T1 (collectInvokedPropertySites) never records a ${siteKey}|${name} pair for it — there is no static name to key on.
  • T3 (collectComputedDispatchTableEvidence) does not fire either: verified against src/extractors/javascript.ts:5523-5538, it only recognizes the const x = TABLE[expr]; x(...) DECLARATOR form (the value must be directly a variable_declarator's value), not a direct TABLE[expr]() call.

So a for...in dispatch idiom gets no invocation evidence for any of the table's properties from any tier. Round 6 closes this soundly by excluding the in variant from the escape check's tracked set — such a table now correctly falls back to escaping — but the underlying capability (crediting a direct, non-declarator computed call like T[k]()) remains unmodeled.

Impact

Recall-only, conservative direction: a genuinely-live handler table dispatched exclusively via for...in + a direct computed call, with no other invocation evidence anywhere in the build, is reported dead by codegraph roles --role dead. This is the same error direction #2088 already accepts for any shape the analysis doesn't recognize (escapes defaults true), not a new regression introduced by round 6's fix.

Suggested fix shape (not binding — decide at execute/fix time)

Extend collectComputedDispatchTableEvidence (#2260) to also recognize a computed access that is DIRECTLY the callee of a call_expression (TABLE[expr]()), not only the const x = TABLE[expr]; x(...) declarator form — mirroring the same call-position check round 6 added to the escape analysis's own member_expression/subscript_expression handling. That would give for (const k in T) T[k]() a T3 evidence path without needing site correlation at all.

Where

Metadata

Metadata

Assignees

No one assigned

    Labels

    follow-upDeferred work from PR reviews that needs tracking

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions