Skip to content

fix(extract): count method calls on instanceof-narrowed values as class-member uses#855

Open
BartWaardenburg wants to merge 2 commits into
mainfrom
fix/issue-845-instanceof-narrowing-member
Open

fix(extract): count method calls on instanceof-narrowed values as class-member uses#855
BartWaardenburg wants to merge 2 commits into
mainfrom
fix/issue-845-instanceof-narrowing-member

Conversation

@BartWaardenburg
Copy link
Copy Markdown
Collaborator

DRAFT: Opened because the reviewer returned FIX (not SHIP). One blocking concern must be resolved before merge: bump CACHE_VERSION in crates/extract/src/cache/types.rs from 107 to 108 with a doc-comment paragraph referencing #845 (same pattern used for #752).

Summary

Adds visit_if_statement to the Oxc AST visitor in crates/extract/src/visitor/visit_impl.rs. When an if statement's test contains x instanceof ClassName (or &&-chained variants), the narrowing x -> ClassName is inserted into binding_target_names before the body is walked. The existing resolve_bound_member_accesses finalization pass then re-emits any x.method() call as ClassName.method, crediting the method as used. A standalone collect_instanceof_narrowings helper recurses through LogicalExpression(&&) and ParenthesizedExpression nodes. Two regression tests are added to crates/extract/src/tests/js_ts/member_access.rs.

Review

Verdict: FIX

  • BLOCKING: Missing CACHE_VERSION bump. The fix changes emitted member_accesses for any file containing an instanceof guard, and member_accesses is serialized into CachedModule (crates/extract/src/cache/types.rs:203). The cache-version doc comment at types.rs:89-92 records the exact precedent: issue unused-class-members FP: methods called only from Svelte <template> member expressions #752 bumped the version for the structurally identical change. With a warm cache, users upgrading will continue to see the false positive until an unrelated edit forces re-extraction. Bump to 108 with a doc-comment paragraph referencing Method call through instanceof narrowing not counted as a class-member use #845.
  • Code fix itself is correct, minimal (2 files, additive), clippy-clean, and fmt-clean. End-to-end validated: getMessage (used only via instanceof-narrowed call) is credited and not reported, while a genuinely-unused sibling method (unusedOne) still reports.
  • Tests are a real regression guard: both new tests in member_access.rs fail before the visitor change and pass after.
  • An integration-level assertion (analyze verdict, not just extract layer) would be stronger but is not blocking.

Closes #845

- Bump extract CACHE_VERSION 107 -> 108: instanceof narrowing populates
  binding_target_names, changing the cached member_accesses for any
  instanceof-bearing file (structurally identical to the #752 precedent).
- Add an analyze-layer regression test + fixture proving the
  unused-class-member false positive is gone end-to-end while genuinely
  unused members on the same class still report.
- Document the detection in .claude/rules/detection.md and CHANGELOG.md.
@BartWaardenburg BartWaardenburg force-pushed the fix/issue-845-instanceof-narrowing-member branch from df1f7a2 to e551df3 Compare June 1, 2026 21:51
@BartWaardenburg BartWaardenburg marked this pull request as ready for review June 1, 2026 21:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Method call through instanceof narrowing not counted as a class-member use

1 participant