Extract resolveFreeCall from resolveCallTarget (SM-13)#756
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Extract the free-function call resolution path into a dedicated `resolveFreeCall(calledName, filePath, ctx)` function that uses `lookupExact` + import-scoped resolution via `ctx.resolve()`. - Free function calls (foo()) now route through `resolveFreeCall` - Swift/Kotlin implicit constructors (User()) delegate to `resolveStaticCall` within `resolveFreeCall` - `resolveCallTarget` dispatches `callForm === 'free'` early, removing the inline freeFormHasClassTarget logic - S0 block simplified to only handle `callForm === 'constructor'` - Global (Tier 3) fallthrough preserved via ctx.resolve() until Phase 5 - 9 new unit tests for resolveFreeCall - All 163 unit tests pass, all 1199 integration resolver tests pass Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/c5f2e73a-259a-438c-b5c8-286b82e3c215 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/c5f2e73a-259a-438c-b5c8-286b82e3c215 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com>
resolveFreeCall from resolveCallTarget (SM-13)
|
@claude review these changes along with the plan on the issue. You need to look for gaps and performance issues. You are also tasked with reviewing the architectureal fit. Also we need to ensure we have coverage for these per languages. Also include other comments in your evaluation. |
|
Claude finished @magyargergo's task in 3m 3s —— View job PR Review: Extract
|
| Language | Free-call pattern | Covered? |
|---|---|---|
| Go | doStuff(), fmt.Println() |
❌ No test |
| Python | def helper() → helper() |
❌ No test |
| Rust | Free functions outside impl |
❌ No test |
| Java | Static imports (import static Utils.doStuff) |
❌ No test |
| Kotlin | User() implicit constructor |
Only tested via proxy (same path as Swift) |
| JavaScript | Module-level function call | ❌ No test |
Go is a particularly important gap — Go codebases make heavy use of free functions and have no method-dispatch syntax, so all calls flow through resolveFreeCall.
3. No test for arity filtering (argCount) in resolveFreeCall
The argCount parameter is threaded through to filterCallableCandidates, but none of the 9 new tests exercise it — every test either has a single candidate or uses the ambiguous (multi-candidate) null-routing test. A test with two overloaded functions differing only in parameter count would verify that argCount actually narrows the result.
4. Swift extension deduplication uses file-path length as a proxy for "primary definition"
call-processor.ts:2004–2008
const sorted = [...filteredCandidates].sort(
(a, b) => a.filePath.length - b.filePath.length,
);
return toResolveResult(sorted[0], tiered.tier);This heuristic assumes the primary definition lives at the shorter path. That assumption breaks for monorepos where the canonical definition is at e.g. packages/core/src/components/Button/Button.swift (long path) and the extension is at src/ext.swift (short path). The same dedup logic existed before SM-13, but there's still no test that validates the shortest-path-wins assumption. Consider adding one to document and guard the behaviour.
5. No test for global (Tier 3) resolution path
The design note at line 1929–1931 explicitly says the function "still falls through to Tier 3 (global) via ctx.resolve()". The existing tests rely on import-scoped (Tier 2, confidence 0.9) and same-file (Tier 1, confidence 0.95) resolution. A test where a function is globally visible but not imported would exercise the Tier 3 path and document its confidence level (expected to be lower, e.g. 0.7 or 0.5 depending on TIER_CONFIDENCE values).
6. No test for preComputedArgTypes disambiguation path (worker path)
The preComputedArgTypes parameter is present in the signature and correctly wired through to matchCandidatesByArgTypes, but it is not tested in any of the 9 new tests. This is the worker path (pre-computed in parse-worker before the main thread resolves). A missing test here means any regression in that branch won't be caught.
7. Enum free-form calls are silently null-routed
Enum is excluded from INSTANTIABLE_CLASS_TYPES (by design, documented at line 94–95), so Kotlin.Color() or Java Color.RED free-call patterns will produce filteredCandidates.length === 0 AND hasClassTarget === false, returning null. This is the stated "pending" position, but there's no test asserting that Enum calls are null-routed with a comment linking back to the tracking work. Worth adding a skipped/pending test to make the gap visible.
Architectural Fit
The SM-13 extraction fits cleanly into the established pattern:
- ✅
resolveCallTargetdispatches oncallForm === 'free'before any other logic (same dispatch order as SM-12 for'constructor') - ✅
tieredOverrideavoids a redundantctx.resolve()call — the one atresolveCallTarget:1370is pre-computed and passed in - ✅
_resolveCallTargetForTestingcorrectly exposes the dispatch path - ✅
freeFormHasClassTargetvariable cleanly removed fromresolveCallTarget - ✅ S0 block now correctly narrowed to
callForm === 'constructor'only
One subtle design point worth noting: when hasClassTarget is true and resolveStaticCall returns null, the constructor-form retry at lines 1977–1981 re-filters tiered.candidates with 'constructor' form. The result may include Constructor nodes that were excluded by the earlier 'free' filter. This is intentional and correct, but the path from "free call with a class target that has no constructor" → "constructor-form retry" → "Swift extension dedup" is not explicitly tested end-to-end.
Performance
No regressions introduced. The hasClassTarget .some() short-circuits on the first matching type; for typical candidate pools (1–5 entries) this is negligible. The main throughput concern remains the pre-existing ctx.resolve() call in resolveCallTarget for all call forms, which is unchanged and justified by the need to pass tiered as tieredOverride.
Minor
- The test file name is
symbol-table.test.tsbut now containsdescribe('resolveFreeCall', ...)at line 2338. This is following the same convention as SM-11 and SM-12 tests (which also live here), but a future rename or split intocall-processor.test.tswould improve discoverability. - The
// SM-13: Free function calls route through resolveFreeCall.comment atresolveCallTarget:1373is consistent with the SM-11/SM-12 comments — good.
Addresses all 7 findings from the PR #756 review comment. Code (R1, finding #1) - Replace the literal `'Class' | 'Struct' | 'Record'` check in `hasClassTarget` with `INSTANTIABLE_CLASS_TYPES.has(c.type)`. Converts an invariant that was previously comment-enforced ("keep this list aligned with INSTANTIABLE_CLASS_TYPES") into one enforced structurally. Any future extension of the set propagates here automatically. The narrower Swift extension dedup block below still uses literal `'Class' | 'Struct'` by design — Swift extensions only produce Class duplicates in practice, Record is deliberately excluded there, and the inline comment now documents that asymmetry. Tests (+12 regression scenarios) Finding #2 — language coverage - Go free function (doStuff()) - Python free function (def helper(): ... helper()) - Rust free function outside any impl block - Java statically-imported function - JavaScript module-level function Each exercises `_resolveCallTargetForTesting` with `callForm='free'` and the language-specific file extension. `resolveFreeCall` has no file-extension branching, so these guard the dispatch chain per language without assuming extractor-specific symbol shapes. Finding #3 — argCount threading - 2-arg overload selected when argCount=2 - 0-arg overload selected when argCount=0 Finding #5 — Tier 3 (global) resolution - Function globally visible but not imported. Asserts exact `TIER_CONFIDENCE.global === 0.5` and `reason === 'global'` to catch silent drift if the tier table is ever refactored. Finding #6 — preComputedArgTypes worker path - String overload matched via preComputedArgTypes=['String'] - Int overload matched via preComputedArgTypes=['int'] (lowercase, mirroring the parse-worker's inferred-literal shape; stored 'Int' is normalized via normalizeJvmTypeName at comparison time) Finding #7 — Enum null-route documentation - Enum-only free call asserts `toBeNull()` with an explanatory comment linking to the INSTANTIABLE_CLASS_TYPES rationale. NOT marked skipped — current behavior is intentional, not broken. Finding #4 — Swift extension dedup guard - Two same-name Class entries at different path lengths; exercises the full dispatch chain: 1. filterCallableCandidates with 'free' strips Class → length 0 2. hasClassTarget triggers resolveStaticCall 3. Homonym ambiguity null-routes per SM-12 round-1 contract 4. Constructor-form retry repopulates with both Classes 5. Dedup block sorts by filePath.length → shortest path wins Verification - `tsc --noEmit` clean - 3064 unit tests pass (+12) - 1766 integration tests pass - Zero regressions Plan: docs/plans/2026-04-09-003-fix-sm13-resolve-free-call-review-findings-plan.md Review: #756 (comment)
Review findings addressed (06ed1c8)All 7 findings from the review. One code fix + 12 new regression tests. Finding-by-finding disposition
Deepening passThe plan ran through a feasibility review before implementation, which caught three things that would have been debug-time surprises:
Scope discipline
Verification
Plan
2 files changed, 273 insertions(+), 11 deletions(-). |
Follow-up to the PR #756 review fix. SM-13 duplicated the Swift extension same-name collision dedup block between `resolveCallTarget` and `resolveFreeCall` — two copies of identical 15-line logic with the same heuristic (`filePath.length` sort, Class/Struct-only, `length > 1` guard). Extract a single shared helper so the two sites cannot drift. Changes - New `dedupSwiftExtensionCandidates(candidates, tier)` helper defined alongside `tryOverloadDisambiguation`, with JSDoc documenting: - The Swift extension scenario it addresses - Why it is intentionally narrower than INSTANTIABLE_CLASS_TYPES (Class/Struct only, not Record — C#/Kotlin records don't exhibit the multi-file definition pattern, widening risks accidental dedup of legitimately distinct record types) - The return-null-on-no-match contract so callers can fall through - `resolveCallTarget` tail dedup (was lines 1593-1610): replaced with a single `dedupSwiftExtensionCandidates` call - `resolveFreeCall` tail dedup (was lines 1994-2012): same replacement - Net line count: -32 insertions, -9 deletions in the consumer sites, +36 for the shared helper + JSDoc Verification - `tsc --noEmit` clean - 3064 unit tests pass (including the R7 Swift dedup guard test added in the previous commit that exercises the full free-form retry chain through this helper) - 1766 integration tests pass - Zero regressions Follows-up on: #756
Deferred items closed out (4726cfc)The two items I originally flagged as "future considerations" have been handled in this PR rather than split off.
|
CI Report✅ All checks passed Pipeline Status
Test Results
✅ All 5679 tests passed 97 test(s) skipped — expand for details
Code CoverageTests
📋 View full run · Generated by CI |
|
@claude review these changes along with the plan on the issue. You need to look for gaps and performance issues. You are also tasked with reviewing the architectureal fit. Also we need to ensure we have coverage for these per languages. Also include other comments in your evaluation. |
|
Claude finished @magyargergo's task in 2m 52s —— View job PR Review: Extract
|
| Language | Basic free call | Constructor (User()) |
Null-route case |
|---|---|---|---|
| TypeScript | ✅ import-scoped + same-file | — | — |
| Swift | ✅ (via R2 test shape) | ✅ R7 dedup | — |
| Kotlin | ✅ (via R2 test shape) | via Swift proxy | — |
| Go | ✅ R2 | — | — |
| Python | ✅ R2 | — | — |
| Rust | ✅ R2 | — | — |
| Java | ✅ R2 (static import proxy) | — | — |
| JavaScript | ✅ R2 | — | — |
| C# | — | ✅ Record target | — |
| PHP | — | — | ✅ Trait null-route |
| PHP free fn | ❌ | — | — |
| Ruby | ❌ | — | — |
| C/C++ | ❌ | — | — |
The R2 tests for Go/Python/Rust/Java/JS exercise the dispatch chain with language-appropriate file extensions, which is the right strategy since resolveFreeCall has no file-extension branching. PHP, Ruby, and C/C++ plain free functions are uncovered, but those are consistent with the broader test gap profile in this file (not a regression from this PR).
Minor / Nits
- The Java R2 test comment accurately notes it guards dispatch routing, not static-import extractor behavior — good self-documentation.
- The
preComputedArgTypestest comment explainingInt → intJVM normalization is valuable and should be preserved. dedupSwiftExtensionCandidatesbeing private (unexported) is correct — it's an implementation detail of the call-processor module.- The test file name (
symbol-table.test.ts) continues to houseresolveFreeCalltests, matching the SM-11/SM-12 precedent. Acceptable for now; a futurecall-processor.test.tssplit would improve discoverability.
Verdict
Approve with minor cleanup. Finding #1 (stale line numbers) is a one-line fix. Findings #2 and #3 are documentation gaps, not bugs. All previous review findings were addressed thoroughly, CI is clean, and coverage delta is positive.
Three documentation-only findings from the approval review. No behavior change, no new tests, no code path modifications. Finding #1 — stale line-number comment - The comment inside `resolveFreeCall` at the `hasClassTarget` site referenced "lines ~1994-2008" for the Swift extension dedup block. Those lines were the inlined pre-SM-13 version; the block has since been extracted to `dedupSwiftExtensionCandidates`. Replaced the line reference with the helper name so future readers don't chase dead line numbers. Finding #2 — fuzzy-widening asymmetry undocumented - `resolveFreeCall` intentionally has no `widenCache` parameter and no D2 fuzzy-widening pass (unlike `resolveCallTarget`'s member-call path). Added an explicit "Asymmetry vs `resolveCallTarget`" paragraph to the JSDoc so a caller comparing the two signatures knows the skipped pass is deliberate and tied to Phase 5. Finding #3 — constructor-form retry reasons undocumented - `resolveStaticCall` can return null for three distinct reasons (empty instantiable pool, homonym ambiguity, ownerless Constructor nodes). The retry below it unconditionally re-filters with `'constructor'` form, which is correct for all three but not obvious. Added a structured three-case comment enumerating each reason and linking (a) to the SM-12 null-route contract, (b) to the R7 dedup test, and (c) to the currently-uncovered ownerless- Constructor path (noted as a future test candidate). Verification - `tsc --noEmit` clean - 175 `resolveFreeCall` + `resolveStaticCall` + sibling tests pass (sanity check — no behavior change expected) - No regressions Follows-up on: #756 (comment)
Final review findings addressed (112fa7c)All 3 documentation-only findings from the approval review. No behavior change, no new tests.
Verification
1 file changed, 42 insertions(+), 6 deletions(-). |
Two low-severity test gaps from PR #756 review comment 4215739052 — previously addressed doc-only, now have concrete test coverage. Finding #3 low — ownerless-Constructor retry path (previously comment-only) - The retry after resolveStaticCall returns null handles three distinct null-return reasons. Cases (a) and (b) were already tested (Interface/ Trait null-route from SM-12, Swift shadowing dedup from R7). Case (c) — resolveStaticCall step-4 bailout when the tiered pool contains ownerless Constructor nodes — was only covered by a comment. - New test: Class + ownerless Constructor in tiered pool, callForm='free'. Exercises the full chain: 1. resolveStaticCall step 3 walks classCandidates via lookupMethodByOwner — ownerless Constructor not in methodByOwner, nothing found. 2. Step 4 detects Constructor in tiered pool, bails with null. 3. resolveFreeCall retry re-runs filterCallableCandidates with 'constructor' form, which prefers Constructor over Class per CONSTRUCTOR_TARGET_TYPES ordering. 4. Single survivor returned. - Asserts the Constructor node (not the Class) is the resolved target. Low — PHP free function coverage gap - The language coverage table in the same review flagged PHP free functions (top-level `function helper()` outside any class) as uncovered. Added a test mirroring the existing Go/Python/Rust/Java/ JS language tests — exercises the `.php` dispatch path for free calls. Ruby and C/C++ remain uncovered; deferred to a future round since those languages also have other gaps in the broader test file. Verification - `tsc --noEmit` clean - 3066 unit tests pass (+2 new regression tests) - 1766 integration tests pass - Zero regressions Follows-up on: #756 (comment)
Two low-severity test gaps addressed (d56b85d)Previous commit addressed finding #3 with a three-reason comment but left case (c) uncovered by a concrete test. This commit adds the two remaining low-priority test coverage items from comment 4215739052. Finding #3 low — ownerless-Constructor retry pathThe retry comment enumerated three null-return reasons from
Case (c) — Asserts the Constructor is the resolved target (not the Class), which is the exact branch the retry comment describes. Low — PHP free function coverage gapThe language coverage table in the review flagged PHP free fn, Ruby, and C/C++ as uncovered. This commit adds the PHP test (top-level Verification
1 file changed, 61 insertions(+). |
…atwari#756) * Initial plan * feat(SM-13): extract resolveFreeCall from resolveCallTarget Extract the free-function call resolution path into a dedicated `resolveFreeCall(calledName, filePath, ctx)` function that uses `lookupExact` + import-scoped resolution via `ctx.resolve()`. - Free function calls (foo()) now route through `resolveFreeCall` - Swift/Kotlin implicit constructors (User()) delegate to `resolveStaticCall` within `resolveFreeCall` - `resolveCallTarget` dispatches `callForm === 'free'` early, removing the inline freeFormHasClassTarget logic - S0 block simplified to only handle `callForm === 'constructor'` - Global (Tier 3) fallthrough preserved via ctx.resolve() until Phase 5 - 9 new unit tests for resolveFreeCall - All 163 unit tests pass, all 1199 integration resolver tests pass Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/c5f2e73a-259a-438c-b5c8-286b82e3c215 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * chore: revert unrelated package-lock.json change Agent-Logs-Url: https://github.com/abhigyanpatwari/GitNexus/sessions/c5f2e73a-259a-438c-b5c8-286b82e3c215 Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> * fix(SM-13): address PR abhigyanpatwari#756 review findings on resolveFreeCall Addresses all 7 findings from the PR abhigyanpatwari#756 review comment. Code (R1, finding abhigyanpatwari#1) - Replace the literal `'Class' | 'Struct' | 'Record'` check in `hasClassTarget` with `INSTANTIABLE_CLASS_TYPES.has(c.type)`. Converts an invariant that was previously comment-enforced ("keep this list aligned with INSTANTIABLE_CLASS_TYPES") into one enforced structurally. Any future extension of the set propagates here automatically. The narrower Swift extension dedup block below still uses literal `'Class' | 'Struct'` by design — Swift extensions only produce Class duplicates in practice, Record is deliberately excluded there, and the inline comment now documents that asymmetry. Tests (+12 regression scenarios) Finding abhigyanpatwari#2 — language coverage - Go free function (doStuff()) - Python free function (def helper(): ... helper()) - Rust free function outside any impl block - Java statically-imported function - JavaScript module-level function Each exercises `_resolveCallTargetForTesting` with `callForm='free'` and the language-specific file extension. `resolveFreeCall` has no file-extension branching, so these guard the dispatch chain per language without assuming extractor-specific symbol shapes. Finding abhigyanpatwari#3 — argCount threading - 2-arg overload selected when argCount=2 - 0-arg overload selected when argCount=0 Finding abhigyanpatwari#5 — Tier 3 (global) resolution - Function globally visible but not imported. Asserts exact `TIER_CONFIDENCE.global === 0.5` and `reason === 'global'` to catch silent drift if the tier table is ever refactored. Finding abhigyanpatwari#6 — preComputedArgTypes worker path - String overload matched via preComputedArgTypes=['String'] - Int overload matched via preComputedArgTypes=['int'] (lowercase, mirroring the parse-worker's inferred-literal shape; stored 'Int' is normalized via normalizeJvmTypeName at comparison time) Finding abhigyanpatwari#7 — Enum null-route documentation - Enum-only free call asserts `toBeNull()` with an explanatory comment linking to the INSTANTIABLE_CLASS_TYPES rationale. NOT marked skipped — current behavior is intentional, not broken. Finding abhigyanpatwari#4 — Swift extension dedup guard - Two same-name Class entries at different path lengths; exercises the full dispatch chain: 1. filterCallableCandidates with 'free' strips Class → length 0 2. hasClassTarget triggers resolveStaticCall 3. Homonym ambiguity null-routes per SM-12 round-1 contract 4. Constructor-form retry repopulates with both Classes 5. Dedup block sorts by filePath.length → shortest path wins Verification - `tsc --noEmit` clean - 3064 unit tests pass (+12) - 1766 integration tests pass - Zero regressions Plan: docs/plans/2026-04-09-003-fix-sm13-resolve-free-call-review-findings-plan.md Review: abhigyanpatwari#756 (comment) * refactor(SM-13): extract dedupSwiftExtensionCandidates shared helper Follow-up to the PR abhigyanpatwari#756 review fix. SM-13 duplicated the Swift extension same-name collision dedup block between `resolveCallTarget` and `resolveFreeCall` — two copies of identical 15-line logic with the same heuristic (`filePath.length` sort, Class/Struct-only, `length > 1` guard). Extract a single shared helper so the two sites cannot drift. Changes - New `dedupSwiftExtensionCandidates(candidates, tier)` helper defined alongside `tryOverloadDisambiguation`, with JSDoc documenting: - The Swift extension scenario it addresses - Why it is intentionally narrower than INSTANTIABLE_CLASS_TYPES (Class/Struct only, not Record — C#/Kotlin records don't exhibit the multi-file definition pattern, widening risks accidental dedup of legitimately distinct record types) - The return-null-on-no-match contract so callers can fall through - `resolveCallTarget` tail dedup (was lines 1593-1610): replaced with a single `dedupSwiftExtensionCandidates` call - `resolveFreeCall` tail dedup (was lines 1994-2012): same replacement - Net line count: -32 insertions, -9 deletions in the consumer sites, +36 for the shared helper + JSDoc Verification - `tsc --noEmit` clean - 3064 unit tests pass (including the R7 Swift dedup guard test added in the previous commit that exercises the full free-form retry chain through this helper) - 1766 integration tests pass - Zero regressions Follows-up on: abhigyanpatwari#756 * docs(SM-13): address PR abhigyanpatwari#756 final review — comment cleanup only Three documentation-only findings from the approval review. No behavior change, no new tests, no code path modifications. Finding abhigyanpatwari#1 — stale line-number comment - The comment inside `resolveFreeCall` at the `hasClassTarget` site referenced "lines ~1994-2008" for the Swift extension dedup block. Those lines were the inlined pre-SM-13 version; the block has since been extracted to `dedupSwiftExtensionCandidates`. Replaced the line reference with the helper name so future readers don't chase dead line numbers. Finding abhigyanpatwari#2 — fuzzy-widening asymmetry undocumented - `resolveFreeCall` intentionally has no `widenCache` parameter and no D2 fuzzy-widening pass (unlike `resolveCallTarget`'s member-call path). Added an explicit "Asymmetry vs `resolveCallTarget`" paragraph to the JSDoc so a caller comparing the two signatures knows the skipped pass is deliberate and tied to Phase 5. Finding abhigyanpatwari#3 — constructor-form retry reasons undocumented - `resolveStaticCall` can return null for three distinct reasons (empty instantiable pool, homonym ambiguity, ownerless Constructor nodes). The retry below it unconditionally re-filters with `'constructor'` form, which is correct for all three but not obvious. Added a structured three-case comment enumerating each reason and linking (a) to the SM-12 null-route contract, (b) to the R7 dedup test, and (c) to the currently-uncovered ownerless- Constructor path (noted as a future test candidate). Verification - `tsc --noEmit` clean - 175 `resolveFreeCall` + `resolveStaticCall` + sibling tests pass (sanity check — no behavior change expected) - No regressions Follows-up on: abhigyanpatwari#756 (comment) * test(SM-13): cover ownerless-Constructor retry + PHP free function Two low-severity test gaps from PR abhigyanpatwari#756 review comment 4215739052 — previously addressed doc-only, now have concrete test coverage. Finding abhigyanpatwari#3 low — ownerless-Constructor retry path (previously comment-only) - The retry after resolveStaticCall returns null handles three distinct null-return reasons. Cases (a) and (b) were already tested (Interface/ Trait null-route from SM-12, Swift shadowing dedup from R7). Case (c) — resolveStaticCall step-4 bailout when the tiered pool contains ownerless Constructor nodes — was only covered by a comment. - New test: Class + ownerless Constructor in tiered pool, callForm='free'. Exercises the full chain: 1. resolveStaticCall step 3 walks classCandidates via lookupMethodByOwner — ownerless Constructor not in methodByOwner, nothing found. 2. Step 4 detects Constructor in tiered pool, bails with null. 3. resolveFreeCall retry re-runs filterCallableCandidates with 'constructor' form, which prefers Constructor over Class per CONSTRUCTOR_TARGET_TYPES ordering. 4. Single survivor returned. - Asserts the Constructor node (not the Class) is the resolved target. Low — PHP free function coverage gap - The language coverage table in the same review flagged PHP free functions (top-level `function helper()` outside any class) as uncovered. Added a test mirroring the existing Go/Python/Rust/Java/ JS language tests — exercises the `.php` dispatch path for free calls. Ruby and C/C++ remain uncovered; deferred to a future round since those languages also have other gaps in the broader test file. Verification - `tsc --noEmit` clean - 3066 unit tests pass (+2 new regression tests) - 1766 integration tests pass - Zero regressions Follows-up on: abhigyanpatwari#756 (comment) --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: magyargergo <11230420+magyargergo@users.noreply.github.com> Co-authored-by: Gergo Magyar <gergomagyar@icloud.com>
Extracts the free-function call resolution path into a standalone
resolveFreeCall(calledName, filePath, ctx), following the same pattern asresolveMemberCall(SM-11) andresolveStaticCall(SM-12).resolveFreeCallNew exported function handling all
callForm === 'free'calls:ctx.resolve()for tiered lookup (lookupExact→ import-scoped → global)resolveStaticCallfor Swift/Kotlin implicit constructors (User())resolveStaticCallmissesresolveCallTargetsimplificationcallForm === 'free'toresolveFreeCallbefore any other logicfreeFormHasClassTargetvariable and the Swift/Kotlin constructor retry blockcallForm === 'constructor'onlyDesign note
resolveFreeCallstill falls through to Tier 3 (global) viactx.resolve(). Fuzzy remains on this path until Phase 5 replaceslookupFuzzy.Tests
9 new unit tests: import-scoped, same-file, null-routing (unknown/ambiguous/Trait), class-target delegation, Record targets,
tieredOverrideshort-circuit, andresolveCallTargetdispatch verification.Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
extension.ladybugdb.com/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/GitNexus/GitNexus/gitnexus/node_modules/.bin/vitest run test/unit/symbol-table.test.ts --reporter=verbose(dns block)/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/GitNexus/GitNexus/gitnexus/node_modules/.bin/vitest run test/unit/symbol-table.test.ts --reporter=verbose ite(sys.executable.encode('utf-8-I(dns block)/home/REDACTED/work/_temp/ghcca-node/node/bin/node node /home/REDACTED/work/GitNexus/GitNexus/gitnexus/node_modules/.bin/vitest run --reporter=verbose xus/�� # We remove slashes and replace spaces with new lines;(dns block)If you need me to access, download, or install something from one of these locations, you can either: