fix(extraction): never fabricate an edge from a call-result receiver (#1748)

A member call whose receiver is itself a call — `d.setdefault(k, []).append(v)`,
`make().run()` — used to drop the receiver at extraction time, degrade to the
bare method name, and exact-match any top-level project symbol of that name
(Python and JavaScript/TypeScript). Keep the inner callee encoded as
`<inner>().<method>` in the TS extractor and native kernel; the name-matcher
refuses to guess for that shape (store-accessor exception only). Based on
#1692, rebased onto main after #1746. Fixes #1683.

Co-authored-by: Colby McHenry <colbymchenry@users.noreply.github.com>
This commit is contained in:
Colby Mchenry
2026-09-08 00:23:08 -05:00
committed by GitHub
co-authored by Colby McHenry
parent bffd50e4f1
commit bb1d3093eb
10 changed files with 226 additions and 3 deletions
+4 -1
View File
@@ -55,7 +55,10 @@ describe('object-literal method extraction', () => {
// so an in-store calls edge will resolve once the pipeline runs.
const fetchUser = result.nodes.find((n) => n.name === 'fetchUser')!;
const fetchUserRefs = result.unresolvedReferences.filter((r) => r.fromNodeId === fetchUser.id);
expect(fetchUserRefs.map((r) => r.referenceName)).toContain('reset');
// `get().reset()` keeps its call receiver (#1683): the ref is the chain
// `get().reset`, which the resolver binds to the store's own `reset`.
expect(fetchUserRefs.map((r) => r.referenceName)).toContain('get().reset');
expect(fetchUserRefs.map((r) => r.referenceName)).not.toContain('reset');
// The action's body wasn't mis-attributed to the file scope (the reason we
// skip the generic body-visit for the store-factory call).