fix(extract): scope member-call resolvers to the sources they own (#10) - #28
Merged
Conversation
The Swift, Python and TypeScript member-call resolvers skipped raw calls
carrying a `lang` tag, and each site claimed that guard kept another
language's data out. It did not: `lang` is stamped only on the cpp, csharp,
java, objc and php raw calls, and those three resolvers are themselves
untagged — so they consumed each other's raw calls. A TypeScript
`Lead.search({})` reached the Python resolver's capitalized-receiver class
arm and minted an EXTRACTED edge into a Python method with no TypeScript
`Lead` anywhere in the corpus. A negative tag check cannot close that by
construction.
Replace it with a positive source-file suffix filter (prior art:
`ruby_resolution._ruby_raw_calls`) and correct the comments at all three
sites. The tagged languages keep matching on `lang`, because C++ and ObjC
share `.h` and a suffix alone cannot tell their raw calls apart.
Also language-scope the Java and C# `type_def_nids` indexes, the last
unfixed copies of the shape #8 fixed for PHP/ObjC: an unscoped index let a
Python `class Lead` type the receiver of a Java `Lead lead; lead.search()`
at INFERRED, and let a foreign class merely sharing the name push the
single-definition guard to 2 and suppress the correct same-language edge.
The suffix tuples now feed both the resolver registration and the scoping,
so the two cannot drift.
Pre-existing defects, not regressions from the Graphify-Labs#1682 work.
Tests: 8 new mixed-corpus cases through the `extract()` seam, each built so
only one resolver can be the miner — the resolver that owns the raw call
refuses it on its own terms, so any surviving edge is a foreign resolver
reaching across. 7 of the 8 were red before this change.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Brings in the #9 (union/intersection + DNF receiver types) and #15 (first-class callables as `indirect_call`) fixes. CHANGELOG.md was the only conflict: both sides edited the "Known open items" bullet, each deleting the clause its own work fixed. Between them every clause is now gone — #9 and #15 on v8's side, #10 on this branch's — so the bullet is deleted outright rather than resolved. All three of v8's new bullets and this branch's #10 bullet are kept. graphify/extract.py auto-merged: v8's changes are confined to `_resolve_php_member_calls`, which this branch does not touch. Verified both sides landed byte-for-byte and that v8's engine.py receiver-table and first-class-callable work is gated on `tree_sitter_php`, so it cannot reach the Swift/Python/TypeScript raw-call filters or the Java/C# type indexes. Full suite: 4049 passed, 36 skipped (4041 on v8 + 8 from this branch). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This was referenced Aug 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #10 (sibling of #8; found in independent review of the Graphify-Labs#1682 feature branch).
What
The Swift, Python, and TypeScript member-call resolvers claimed every untagged raw call — including each other's — so a TypeScript receiver could mint an edge into a Python method at EXTRACTED (the issue's measured repro). The negative
if rc.get("lang"): continueskips could not close this by construction, and their comments asserted a protection that did not hold._raw_call_is_owned), the prior artruby_resolution.pyalready used. Per-resolver suffix tuples are shared between the filters and the resolver registrations so they cannot drift.type_def_nidsindexes, completing the pattern the PHP/ObjC fix established in2e68ec6. Java'sLead lead; lead.search()no longer binds to a Pythonclass Leadat INFERRED..hdual-routing untouched; C++/ObjC suites pass unchanged.e147764merges post-PHP: union- and intersection-typed receivers still mint a same-file bare-name edge (user story 11) #9/PHP: first-class callable $obj->method(...) emits a calls edge; candidate indirect_call #15v8; the auto-merge was verified byte-for-byte against both parents.Follow-up filed
#24 — Swift, Python, TypeScript, and C++ receiver-type indexes are still unscoped (outside this ticket's AC); C++ needs the
.hboth-sets treatment.Test evidence
🤖 Generated with Claude Code