fix(extraction): never fabricate an edge from a call-result receiver - #1692
Open
danusha2345 wants to merge 1 commit into
Open
fix(extraction): never fabricate an edge from a call-result receiver#1692danusha2345 wants to merge 1 commit into
danusha2345 wants to merge 1 commit into
Conversation
…olbymchenry#1683, colbymchenry#1681) A member call whose receiver is itself a call — `d.setdefault(k, []).append(v)`, `make().run()` — lost the receiver at extraction and degraded to the bare method name, which exact-matched (or fuzzy-matched) any top-level project symbol of that name: a call edge from an unrelated function, in Python and JavaScript alike. Keep the inner callee, encoded as `<inner>().<method>` like the Java/C++ chains, in the wasm walker and both kernels; an inner callee with no static name emits nothing. The resolver owns the chain shape for TS/JS/Python: it is routed past the import strategy (which bound `useStore.getState().reset` to the imported store constant) and never reaches the fuzzy split. The one fallback kept is the store-accessor idiom — Zustand's `get()` / `useStore.getState()` followed by a method name with exactly one callable in the project — which the object-literal store coverage relies on. Everything else resolves to nothing: what an inner call returns is not knowable from its name.
danusha2345
pushed a commit
to danusha2345/codegraph
that referenced
this pull request
Sep 5, 2026
…uiltin-method name The extractor hunk is dropped: it changes src/extraction/tree-sitter.ts only, which the kernel (python.rs) supersedes at runtime, and the call-receiver shape it targets is already covered in both arms by colbymchenry#1692.
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 #1683. Also covers the false-positive half of #1681.
Problem
A member call whose receiver is itself a call —
d.setdefault(k, []).append(v),d.items().get(k),make().run()— lost the receiver at extraction time and degraded to the bare method name. The bare name then exact-matched (or, via the fuzzy split, fuzzy-matched) any top-level project symbol of that name — acallsedge from an unrelated function, reproduced in Python and JavaScript alike, so it is the shared extractor, not a per-language rule.Change
tsjs/extractors.rs,python.rs): for TS/JS/Python a call receiver is kept and encoded as<inner>().<method>— the marker the Java / Kotlin / C++ chains already use, which no plain name can match. An inner callee with no static name ((await x)(),arr[0]()) emits nothing: a silent miss, never a wrong edge. The inner call is visited on its own either way, somake()keeps its edge.resolveViaImport(which bounduseStore.getState().resetto the imported store constant, so the method was never looked up) and stops before the fuzzy strategy for these three languages. The one fallback kept is the store-accessor idiom the object-literal coverage relies on — Zustand'sget()inside the factory anduseStore.getState()outside it, followed by a method name with exactly one callable in the project. Everything else resolves to nothing: what an inner call returns is not knowable from its name (an earlier draft that allowed any project-rooted chain bounddb.prepare(sql).all()to a project function namedallon this repo's own index — 363 such edges — which is the very defect).torture.jsandtorture.pygain the shapes.Verification
__tests__/call-receiver-no-fabrication.test.ts: the issue's Python and JS repros produce no edge into the same-named top-level functions, the inner call keeps its edge, the encoding is as stated, a receiver with no static callee is dropped. Onmainthe fabricatedappend/get/runcallers appear.object-literal-methods(Zustandget().reset()anduseStore.getState().reset()) still resolves; its extraction assertion is updated to the chain-encoded ref.callsedges landing on top-level functions named like collection methods drop from 22 → 5, 31 → 20, 2 → 1; C unchanged.Re-index after upgrading.
🤖 Generated with Claude Code