Skip to content

follow-up: receiver-type-aware invoked-property matching to reduce dead-code false negatives #2088

Description

@carlos-alm

Deferred from PR #2034 review.

Original reviewer comment: inline comment — #2034 (comment)

Context:

collectInvokedPropertyNames (src/domain/graph/builder/call-resolver.ts, mirrored as collect_invoked_property_names in crates/codegraph-core/src/domain/graph/builder/stages/build_edges.rs) adds a property name to its evidence set whenever ANY call in the processed files has a non-empty receiver and that name — with no check that the receiver is plausibly the same dispatch-table object referenced by the object-literal being evaluated. A completely unrelated logger.resolve() or promise.resolve() call anywhere in the codebase will add resolve to the set and prevent { resolve: neverCalled } from being flagged dead, even if the actual dispatch table is never read.

This is the conservative error direction (false negative for dead-code — it can never misclassify genuinely live code as dead), so it was accepted as-is for #2034: that PR's stated scope was "require any invocation evidence" as a deliberately coarse "one hop further" heuristic (see the doc comment on collectInvokedPropertyNames), not precise receiver-type correlation. Tightening it now would require:

  • Extending the existing points-to/type-map machinery to track each receiver call site's inferred type/binding.
  • Correlating that inferred type back to the specific object-literal (or dispatch-table variable) that defines the property being checked.
  • Implementing this identically in both the WASM/TS and native Rust engines, per this repo's dual-engine parity requirement.

That's a nontrivial dataflow precision improvement, not a small tweak, so it's being tracked separately rather than folded into #2034's narrower "any evidence at all" fix.

What the fix entails: teach collectInvokedPropertyNames/resolveFallbackTargets (and their Rust mirrors) to only count a x.name(...) call as evidence for a given object-literal's { name: fn } property when x's resolved type/binding plausibly refers to that same object (e.g. via the existing typeMap/points-to infrastructure), rather than matching on bare property name alone.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

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