Skip to content

fix(incremental): seed callee::restName typeMap keys and pass callerName for Phase 8.3f#1404

Merged
carlos-alm merged 5 commits into
mainfrom
fix/incremental-caller-name-1369
Jun 9, 2026
Merged

fix(incremental): seed callee::restName typeMap keys and pass callerName for Phase 8.3f#1404
carlos-alm merged 5 commits into
mainfrom
fix/incremental-caller-name-1369

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

  • buildCallEdges in the incremental rebuild path (incremental.ts) was missing two things needed for Phase 8.3f scoped-key lookup to work after a file edit:
    1. TypeMap not seeded with scoped keys: objectRestParamBindings × paramBindings were not cross-referenced to seed callee::restName entries (e.g. f2::rest) in the typeMap. Without this seeding the scoped-key fallback in resolveByMethodOrGlobal (typeMap.get(callerName::receiver)) has nothing to find.
    2. caller.callerName not passed: Even with scoped keys in the typeMap, the ${callerName}::${effectiveReceiver} lookup never fired because callerName was not passed to resolveCallTargets.
  • Also ports the same-class this.method() fallback and definePropertyReceivers fallback from the full-build path into buildCallEdges, completing incremental/full-build parity for these resolution patterns.

Test plan

Closes #1369

…ame in buildCallEdges

Incremental rebuilds using buildCallEdges (incremental.ts) were missing two
things needed for Phase 8.3f scoped-key resolution (#1358 / #1369):

1. The typeMap was not seeded with callee::restName entries from
   objectRestParamBindings × paramBindings. Without this seeding the scoped
   key `callee::restName` (e.g. `f2::rest`) is absent from the map, so
   resolveByMethodOrGlobal's third fallback (`typeMap.get(callerName::receiver)`)
   has nothing to find and the rest-param call goes unresolved.

2. caller.callerName was not passed to resolveCallTargets, so even if the
   scoped key was present in the typeMap (e.g. from WASM extraction), the
   `${callerName}::${effectiveReceiver}` lookup in resolveByMethodOrGlobal
   never fired.

Fix: mirror what buildObjectRestParamPostPass (native full-build post-pass)
and buildCallEdgesJS (WASM full-build path) already do:
- Compute restNameCallees to know how many callees share a rest name.
- Seed typeMap[callee::restName] for each objectRestParamBinding × paramBinding pair.
- Also seed the unscoped key when only one callee uses that rest name, so
  resolution still works when callerName is null (findCaller couldn't match).
- Pass caller.callerName to resolveCallTargets (already present from #1389).

Also syncs call-resolver.ts and build-edges.ts with the scoped-key changes
from PR #1368 (merged to main separately), which this branch was missing.

docs check acknowledged

Closes #1369
@greptile-apps

greptile-apps Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes two missing pieces in the incremental rebuild path (buildCallEdges in incremental.ts) that caused Phase 8.3f scoped-key resolution to fail after a file edit: the typeMap was not seeded with callee::restName scoped keys, and caller.callerName was not forwarded to resolveCallTargets. It also ports the same-class this.method() fallback and definePropertyReceivers fallback to achieve full parity with the full-build path.

  • typeMap seeding: The new loop mirrors buildObjectRestParamPostPass exactly — same confidence value (0.65), same scoped-key guard (!typeMap.has(scopedKey)), same unscoped-key-only-when-singleton logic — so incremental and full-build produce identical entries.
  • callerName forwarding: resolveCallTargets now receives caller.callerName, enabling the scoped ${callerName}::${effectiveReceiver} lookup in resolveByMethodOrGlobal that was silently a no-op before.
  • Integration test: The new issue-1369 test runs a full build followed by a file-touch incremental rebuild and asserts that both f1→m1 and f2→m2 edges are preserved with no cross-edges, directly covering the regression scenario.

Confidence Score: 5/5

Safe to merge — the changes close a gap where incremental rebuilds silently produced incomplete call graphs for files using shared rest-param names.

The typeMap seeding block is a line-for-line match to buildObjectRestParamPostPass (same confidence constant, same guard conditions, same unscoped-key-when-singleton rule). The callerName forwarding is a one-argument addition to an already-existing call. Both fallbacks are direct ports from the verified full-build path. The integration test covers the exact regression scenario end-to-end.

No files require special attention.

Important Files Changed

Filename Overview
src/domain/graph/builder/incremental.ts Added typeMap scoped-key seeding (mirroring buildObjectRestParamPostPass), callerName forwarding, same-class this.method() fallback, and definePropertyReceivers fallback — all faithfully matching the full-build path logic with no obvious divergences.
tests/integration/issue-1369-incremental-rest-param-callerName.test.ts New integration test using the same fixture as #1358; covers full build followed by incremental rebuild and asserts correct edges with no cross-contamination.

Sequence Diagram

sequenceDiagram
    participant BG as buildGraph (incremental)
    participant BCE as buildCallEdges
    participant TM as typeMap
    participant FC as findCaller
    participant RCT as resolveCallTargets
    participant RBMG as resolveByMethodOrGlobal

    BG->>BCE: symbols (calls, objectRestParamBindings, paramBindings)
    BCE->>TM: seed callee::restName keys (Phase 8.3f)
    note over TM: e.g. f2::rest → { type: obj2 }

    loop for each call
        BCE->>FC: findCaller(call, definitions)
        FC-->>BCE: "caller { id, callerName }"
        BCE->>RCT: resolveCallTargets(..., callerName) ← NEW
        RCT->>RBMG: resolveByMethodOrGlobal(typeMap, callerName)
        RBMG->>TM: typeMap.get("f2::rest") ← scoped key now found
        TM-->>RBMG: "{ type: obj2 }"
        RBMG-->>RCT: targets [m2]
        RCT-->>BCE: "{ targets [m2], importedFrom }"

        alt targets empty AND this.method() call
            BCE->>BCE: same-class fallback: ClassName.methodName lookup
        end
        alt targets empty AND definePropertyReceivers
            BCE->>BCE: definePropertyReceivers fallback
        end
    end
Loading

Reviews (4): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

@github-actions

github-actions Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

1 functions changed5 callers affected across 2 files

  • buildCallEdges in src/domain/graph/builder/incremental.ts:485 (5 transitive callers)

@carlos-alm

Copy link
Copy Markdown
Contributor Author

@greptileai

carlos-alm and others added 3 commits June 8, 2026 11:28
Resolved one-line conflict in buildCallEdges: kept main's
const/let split pattern (targets: initialTargets → let targets)
and removed duplicate this-method and definePropertyReceivers
fallback blocks introduced by the merge.
@carlos-alm carlos-alm merged commit 6f7189e into main Jun 9, 2026
22 checks passed
@carlos-alm carlos-alm deleted the fix/incremental-caller-name-1369 branch June 9, 2026 06:08
@github-actions github-actions Bot locked and limited conversation to collaborators Jun 9, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(incremental): pass callerName to resolveCallTargets in incremental path for Phase 8.3f scoped-key lookup

1 participant