Skip to content

Navigation Menu

Sign in
Sign up

Let builtin named member calls through to cross file resolution - #3392

Open
ayushcodes10 wants to merge 1 commit into
Graphify-Labs:v8 from
ayushcodes10:fix-3381-builtin-member-calls
Open

Let builtin named member calls through to cross file resolution #3392
ayushcodes10 wants to merge 1 commit into
Graphify-Labs:v8 from
ayushcodes10:fix-3381-builtin-member-calls

Conversation

@ayushcodes10

@ayushcodes10 ayushcodes10 commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

What

_LANGUAGE_BUILTIN_GLOBALS is one union across every language, right for a bare call (String(x) really would become a god node) but wrong applied to a member call: open is a Python builtin and Set a JavaScript one, so session.open() in Swift or _server.Set() in C# was silently discarded outright — no same-file edge, but also no raw_calls entry, so cross-file resolution never got a chance to try it.

A member call carries a receiver, so it isn't the ambiguous case the union guards against. Lets it reach the existing tgt_nid = None deferral every receiver-typed resolver already uses for other cases, so it can only ever reach an edge through a guarded, receiver-typed resolver — never the unguarded bare-name path a real god node would need.

Verified

  • Python: Session.open() cross-file class-qualified call now resolves (EXTRACTED).
  • Swift: reproduced the reporter's own real-world example directly — AppleReadyStreamFinder.find -> RemuxPlayback.open now resolves (INFERRED, via the field-typed receiver resolver).
  • Same-file god-node guard still holds: other.open() does not bind to an unrelated same-file bare open() function, and a bare call to the actual builtin open(...) still produces no phantom edge.
  • Full suite green, no regressions.

Scope: go.py/rust.py intentionally not touched

The issue asks for the identical change in extractors/go.py (~L480) and extractors/rust.py (~L372) too. I traced where their raw_calls entries for member calls actually go: extract.py's shared cross-file resolver skips every is_member_call entry unconditionally —

# Skip member-call callees: obj.log() → "log" has no import evidence
# and collides with any top-level function named "log" in the corpus.
if rc.get("is_member_call"):
 continue

— regardless of builtin status, and neither Go nor Rust has a dedicated receiver-typed resolver the way Python (_resolve_python_member_calls), Java, C#, Swift, TypeScript, C++, and Objective-C do. Making the same edit there would be safe (it wouldn't reintroduce the god-node risk) but currently has zero observable effect on the final graph, since nothing downstream would ever consume the preserved raw_calls entry. Rather than ship an inert change, I left it out — worth revisiting once either language gets its own receiver-typed cross-file resolver.

Fixes #3381.

_LANGUAGE_BUILTIN_GLOBALS is one union across every language, right
for a BARE call (String(x) really would become a god node) but wrong
for a MEMBER call. open is a Python builtin and Set a JavaScript one,
so session.open() in Swift or _server.Set() in C# named after another
language's builtin was silently discarded outright: no same file
edge, but also no raw_calls entry, so cross file resolution never got
a chance to try it.
A member call carries a receiver, so it is not the ambiguous case the
union guards against. Lets a builtin named member call reach the
existing tgt_nid = None deferral every receiver typed resolver
already relies on for other cases (a capitalized Python receiver, any
Java member call, and so on), so it can only ever reach an edge
through a guarded, receiver typed resolver, never the unguarded
bare name path a real god node would need.
Verified against real cross file setups for Python (class qualified
call) and Swift (field typed receiver, reproducing the reporter's own
AppleReadyStreamFinder.find -> RemuxPlayback.open example), plus that
a same file member call still cannot bind to an unrelated bare
function sharing the builtin name.
Scoped to the shared engine only. go.py and rust.py carry the same
outer filter, and the reported issue asks for the same change there
too, but tracing where their raw_calls entries actually go shows the
shared cross file resolver skips every is_member_call entry
unconditionally (extract.py, the "obj.log() has no import evidence"
guard) regardless of builtin status, and neither language has a
dedicated receiver typed resolver the way Python, Java, C#, Swift,
TypeScript, C++, and Objective-C do. Making the same change there
would be safe but currently inert, so left out rather than shipping a
change with no verifiable effect; worth revisiting once either
language gets its own receiver typed cross file resolver.
Fixes Graphify-Labs#3381.

Copy link
Copy Markdown
Contributor Author

@safishamsi opened this against #3381 (a member call named after another language's builtin, e.g. Swift's session.open() colliding with Python's open, was silently discarded with no raw_calls entry at all). Verified against real cross-file Python and Swift setups, including the reporter's own AppleReadyStreamFinder.find -> RemuxPlayback.open example. Scoped to the shared engine only; the PR description explains why I left go.py/rust.py out (traced their raw_calls path and it's currently inert there, no receiver-typed resolver to consume it). Happy to address any feedback.

@graphify-labs graphify-labs Bot left a comment
edited
Loading

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Graphify reviewed this change.

Looks safe to merge — no coupling regressions and no blocking issues, checked against the code graph (not a self-assessment).

Formal verification. No changes could be formally verified in this run.


Graphify review — findings

Fixes member calls named after another language's builtin (Session.open(), _server.Set()) being discarded entirely — they now emit a raw_calls entry so cross-file resolution can bind them, while still forcing tgt_nid = None so they only ever resolve through the guarded, receiver-typed path and never fall back to an unrelated bare function of the same name. Bare calls remain filtered against _LANGUAGE_BUILTIN_GLOBALS to avoid god nodes. Adds tests covering both the cross-file resolution and the god-node guard.

No blocking issues surfaced. 3 lower-confidence candidates did not survive cross-model review.

Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 1008 functions depend on the 607 functions this change touches.

Health — this change adds coupling hotspots:

  • new: _extract_generic() — 18 callers, 26 callees
  • new: extract_js() — 85 callers, 4 callees
  • new: extract_xaml() — 19 callers, 17 callees
  • new: extract_objc() — 27 callers, 9 callees
  • new: extract_julia() — 17 callers, 7 callees
  • new: extract_cpp() — 27 callers, 3 callees
  • new: extract_vue() — 10 callers, 7 callees
  • new: walk() — 1 callers, 58 callees
  • ...and 8 more — each is listed as a finding

Verification — 1008 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 948 function(s) in the blast radius were not formally verified this run

Formal verification

Could not verify: Could not verify \_extract\_generic.

The verifier did not have enough to check \_extract\_generic, so it is saying so rather than guessing. No false assurance is the whole point.

Guarantee: No guarantee either way, this is an honest abstention, not a pass.

Note: Reason: parameter `path` is annotated `Path` — outside the synthesizable primitive/collection set

· 16 more finding(s) on lines outside this diff (see the check run).

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

Reviewers

@graphify-labs graphify-labs[bot] graphify-labs[bot] left review comments

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

_LANGUAGE_BUILTIN_GLOBALS deletes member calls named after another language's builtins (all grammars)

1 participant

AltStyle によって変換されたページ (->オリジナル) /