Skip to content

fix: resolve renamed-import receiver calls in qualified-method lookup#1971

Open
carlos-alm wants to merge 1 commit into
fix/issue-1824-dynamic-import-destructuring-rename-const-a-bfrom
fix/issue-1825-renamed-import-used-as-a-receiver-import-x-as
Open

fix: resolve renamed-import receiver calls in qualified-method lookup#1971
carlos-alm wants to merge 1 commit into
fix/issue-1824-dynamic-import-destructuring-rename-const-a-bfrom
fix/issue-1825-renamed-import-used-as-a-receiver-import-x-as

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

  • resolveByReceiver's qualified-name resolution steps (typed-method lookup, prototype-alias lookup, and direct-qualified-method lookup) built the symbol-table lookup key from either the call receiver's local text or its typeMap-resolved type name. Neither accounted for a renamed import binding (import { X as Y } from './mod'; Y.method()) — the symbol table stores definitions under their declared name (X), not the importing file's local alias (Y), so the qualified lookup (Y.method) missed and the call was silently dropped with no calls edge.
  • Fixed by threading importedOriginalNames (the local-alias → original-name map already built for direct call-name resolution, codegraph exports does not credit consumers that import via a rename (import { X as Y }) #1730) through resolveByMethodOrGlobal into resolveByReceiver, and de-aliasing the qualifier immediately before each qualified-name is built:
    • Direct-qualified-method path (issue's exact reported repro): NsAlias.doThing() where NsAlias is a renamed import of an object literal NamespaceObj — now resolves via NamespaceObj.doThing.
    • Typed-method / prototype-alias path (same underlying gap, same function): new Bar() where Bar is a renamed import of class Foo — the typeMap records the receiver's type as the local alias text (Bar), so resolveViaTypedMethod/resolveViaPrototypeAlias had the identical bug; now resolves via Foo.method.
  • Mirrored in the native Rust resolver (resolve_call_targets in crates/codegraph-core/src/domain/graph/builder/stages/build_edges.rs) — both engines now produce identical edges.

Test plan

  • Added tests/integration/issue-1825-renamed-import-receiver.test.ts — verifies both the direct-qualified and typed-method paths resolve correctly on both WASM and native engines, and that no spurious edge is created against the local alias name.
  • npm test — full suite green (228 test files, 3761 passed, 0 failed)
  • npm run lint — clean
  • cargo test --lib — 529 passed
  • Native addon rebuilt, codesigned, verified directly against both engines
  • Manually reverted the fix (via patch) and confirmed all 4 new assertions fail without it, then reapplied and confirmed they pass — verifying the test actually exercises the bug

Fixes #1825

`resolveByReceiver`'s qualified-name lookups (typed-method, prototype-alias,
and direct-qualified-method) built the symbol-table key from the call
receiver's local text or its typeMap-resolved type name, neither of which
accounts for a renamed import binding (`import { X as Y } from './mod'; Y.method()`).
The symbol table stores definitions under their declared name (X), not the
importing file's local alias (Y), so the lookup silently missed and no
`calls` edge was created.

Thread `importedOriginalNames` (already computed for direct call-name
resolution, #1730) through `resolveByMethodOrGlobal` into `resolveByReceiver`,
and de-alias the qualifier immediately before building each qualified lookup
key. Mirrored in the native Rust resolver (`resolve_call_targets`).
@greptile-apps

greptile-apps Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes receiver-based calls through renamed imports. The main changes are:

  • Pass the renamed-import map into TypeScript receiver resolution.
  • De-alias typed, prototype, and direct qualified method lookups.
  • Mirror the same behavior in the Rust edge builder.
  • Add integration coverage for WASM and native engine paths.

Confidence Score: 5/5

This looks safe to merge after a small test cleanup hardening.

  • The resolver changes keep alias lookup scoped to the importing file.
  • Non-renamed and already-original names keep the old lookup behavior.
  • The only issue found is a teardown path in the new test when setup fails early.

tests/integration/issue-1825-renamed-import-receiver.test.ts

Important Files Changed

Filename Overview
src/domain/graph/resolver/strategy.ts Adds receiver/type qualifier de-aliasing before method lookup.
src/domain/graph/builder/call-resolver.ts Threads the renamed-import map into receiver-based resolution.
crates/codegraph-core/src/domain/graph/builder/stages/build_edges.rs Mirrors renamed-import receiver lookup behavior in the native resolver.
tests/integration/issue-1825-renamed-import-receiver.test.ts Adds regression coverage for renamed-import receiver calls across engine modes.

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix: resolve renamed-import receiver cal..." | Re-trigger Greptile

Comment on lines +77 to +80
afterAll(() => {
fs.rmSync(tmpWasm, { recursive: true, force: true });
fs.rmSync(tmpNative, { recursive: true, force: true });
});

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Cleanup Uses Uninitialized Paths

If setup throws before both temp directory variables are assigned, this cleanup calls fs.rmSync with undefined. The original setup error is then followed by a teardown TypeError, and any directory created before the failure can be left behind.

Suggested change
afterAll(() => {
fs.rmSync(tmpWasm, { recursive: true, force: true });
fs.rmSync(tmpNative, { recursive: true, force: true });
});
afterAll(() => {
if (tmpWasm) fs.rmSync(tmpWasm, { recursive: true, force: true });
if (tmpNative) fs.rmSync(tmpNative, { recursive: true, force: true });
});

Fix in Claude Code

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Codegraph Impact Analysis

3 functions changed15 callers affected across 3 files

  • resolveByMethodOrGlobal in src/domain/graph/builder/call-resolver.ts:236 (10 transitive callers)
  • resolveCallTargets in src/domain/graph/builder/call-resolver.ts:270 (13 transitive callers)
  • resolveByReceiver in src/domain/graph/resolver/strategy.ts:223 (7 transitive callers)

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant