feat: language-aware code intelligence — symbol resolution, MRO, constructor discrimination#238
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Implement full MRO computation for multi-language inheritance hierarchies: - HAS_METHOD edges: Class→Method ownership edges emitted during parsing (both worker pool and sequential fallback paths) - Method signatures: extract parameterCount and returnType from AST nodes - C# heritage fix: distinguish EXTENDS vs IMPLEMENTS for base_list captures using symbol table lookup + I[A-Z] naming heuristic fallback - MRO processor (Phase 4.5): walks inheritance DAG, detects method-name collisions across parents, applies language-specific resolution: - C++: leftmost base class in declaration order wins - C#/Java: class method wins over interface default - Python: C3 linearization with cycle detection - Rust: no auto-resolution (requires qualified syntax) - Default: first definition in BFS order wins - OVERRIDES edges emitted for resolved method collisions - KuzuDB schema: Method table extended with parameterCount/returnType; dedicated CSV writer and COPY query for 10-column Method rows - MCP tools: updated Cypher examples for HAS_METHOD, OVERRIDES, diamond 72 tests across 5 test files covering MRO resolution, HAS_METHOD edges, method signature extraction, C# heritage resolution, and integration tests across C#/Rust/Python/TS/Java/C++.
83ee864 to
0334587
Compare
CI Report✅ All checks passed Pipeline Status
Test Results✅ 1636 passed Code CoverageCombined (Unit + Integration)
Coverage breakdown by test suiteUnit Tests
Integration Tests
Coverage thresholds are auto-ratcheted — they only go upVitest 📋 View full run · Generated by CI |
Introduces a shared 3-tier resolveSymbol function used by both heritage-processor and call-processor: 1. Same-file (lookupExactFull — authoritative) 2. Import-scoped (filtered by ImportMap — high confidence) 3. Global fuzzy (first match — low confidence fallback) Adds lookupExactFull to SymbolTable returning full SymbolDefinition with type info needed for heritage Class/Interface disambiguation.
|
Claude finished @magyargergo's task in 3m 24s —— View job Code Review
Great work on this feature — the overall architecture is clean and the test coverage is solid. Here are my findings, grouped by severity. Bugs / Critical Issues1. KuzuDB schema missing HAS_METHOD edges are emitted for 2. For Rust's current.children?.find((c: any) =>
c.type === 'type_identifier' || c.type === 'identifier' || c.type === 'name'
);…will find Design / Semantic Issues3. MRO emits OVERRIDES for
4. Consider a hierarchy where 5. graph.addRelationship({
sourceId: classId,
targetId: resolution.resolvedTo, // a methodId
type: 'OVERRIDES',The edge goes from the child class to the winning ancestor method. Cypher queries expecting Minor Issues6. Default language fallback is const language = classNode.properties.language ?? 'typescript';If TypeScript ever gets a dedicated MRO case added to the switch, this silent fallback would bypass the 7.
8. Go uses a different AST structure for return types (no 9. Symbol resolver Tier 3 returns the first global match silently ( return allDefs[0];When there are multiple classes with the same name across files, the first-indexed match wins with no signal about the ambiguity. This could cause incorrect EXTENDS/IMPLEMENTS edges to be drawn to the wrong class. Consider returning Observations (not bugs)
Overall the implementation is well-structured and the test suite is thorough. The |
- lookupExactFull now O(1) via direct SymbolDefinition storage in fileIndex
(shared object references with globalIndex — zero additional memory)
- Added resolveSymbolInternal() preserving { definition, tier, candidateCount }
for test assertions and logging
- Tier 3 now returns null when multiple global candidates exist instead of
arbitrary allDefs[0] — a wrong edge is worse than no edge
- call-processor: renamed fuzzy-global → unique-global, removed dead branch
- 12 new tests: tier assertions, ambiguous refusal per language family,
heritage false-positive guard, O(1) shared reference verification
Phase 5 critical fixes from all-language analysis:
- Python: add relative_import query capture (PEP 328) — `.models`, `..utils`
were silently dropped, producing zero ImportMap entries
- Rust: extract prefix from grouped imports `crate::module::{A, B}` — brace
groups previously failed resolution entirely
- Swift: use normalizedFileList for Windows path compatibility in module
import resolution (matches Go's resolveGoPackage pattern)
- MRO: fix c_sharp → csharp language name mismatch (enum is 'csharp'),
add Kotlin to C#/Java resolution rules (class method wins over interface)
…resolution Add 32 integration tests across 6 language fixtures (TypeScript, C#, C++, Java, Python, Rust) with exact toBe/toEqual assertions validating heritage edges, import resolution, and trait implementations. Fix C/C++ import resolution bug where dot-to-slash conversion mangled include paths (e.g. "animal.h" became "animal/h"). Now skips conversion for C/C++ languages which use actual file paths in #include directives.
…handle Rust grouped imports
- Gate I[A-Z] naming heuristic to C#/Java only (was firing for all languages)
- Swift unresolved types default to IMPLEMENTS (protocol conformance is the norm)
- Add tree-sitter query for Swift extension protocol conformance (extension Foo: Protocol)
- Handle Rust top-level grouped imports (use {crate::a, crate::b}) in both import loops
- Add 4 new heritage-processor tests (TypeScript refusal, Swift default, Swift Tier 1)
Add Go struct embedding detection (anonymous fields → EXTENDS edges) via new tree-sitter heritage query with named-field filtering in both parse-worker and heritage-processor paths. Implement PackageMap optimization for Go cross-package resolution: replace O(N) file-level ImportMap expansion with directory-level suffix matching (Tier 2b in symbol resolver). Graph IMPORTS edges are preserved via addImportGraphEdge split. Remove overly broad @definition.type from GO_QUERIES that was double-matching structs/interfaces as TypeAlias nodes, breaking Tier 3 unique-global resolution. Add Go fixture (go-pkg) with Admin→User embedding, cross-package calls, and 7 integration tests covering structs, functions, imports, calls, and heritage edges.
Adds a kotlin-heritage fixture and 7 integration tests validating class inheritance, interface implementation, JVM-style import resolution, and symbol-table-driven EXTENDS/IMPLEMENTS disambiguation via Kotlin delegation specifiers.
…ages - Extract language-specific resolvers from import-processor.ts into resolvers/ directory (P7): jvm, go, csharp, php, rust, standard, utils - import-processor.ts reduced from 1412 to 711 lines (50% reduction) - Add comprehensive PHP integration tests: PSR-4 imports, traits, enums, heritage edges, method calls, MRO overrides - Add ambiguous symbol resolution tests for all 9 languages verifying correct disambiguation via import chains - Split monolithic lang-resolution.test.ts (1080 lines) into 9 per-language files under test/integration/resolvers/ with shared helpers
|
@claude review this PR since it's been changed since you reviewed it. |
|
Claude finished @magyargergo's task in 4m 6s —— View job Code Review (Updated)
|
…IDES Bugs fixed: - Add 13 missing FROM/TO pairs in RELATION_SCHEMA for HAS_METHOD edges (Class/Interface/Struct/Trait/Impl/Record to Method/Constructor/Property) - Fix findEnclosingClassId to pick implementing type for Rust impl Trait for Struct blocks (was picking trait name) - Exclude Property nodes from MRO OVERRIDES collision detection - Change MRO language fallback from typescript to unknown Tests added: - Unit: Property OVERRIDES exclusion (2 tests), Rust impl Trait for Struct name resolution (2 tests), schema HAS_METHOD pair coverage - Integration: no OVERRIDES targets Property nodes across all 9 languages - PHP fixture: added shared $status property to both traits to create real collision scenario for Property OVERRIDES exclusion test Documentation: - OVERRIDES edge direction (Class to Method), Go return type gap, BFS first-reach heuristic limitation
- Fix same-file confidence (0.85 → 0.95) to correctly outrank import-scoped (0.9) - Fix Tier 1 overload preservation: use globalIndex filter instead of fileIndex lookup - Add callable-kind guard: refuse CALLS edges to Interface and Enum symbols - Fix Kotlin countCallArguments: handle call_suffix → value_arguments nesting - Fix Kotlin extractFunctionName: add simple_identifier to fallback search - Strictly type findParameterList and countCallArguments (remove all `any`) - Add arity-based call resolution integration tests for 9 languages - Add unit regression tests for Interface/Enum CALLS refusal
collectRustBindings was extracting the path segment (e.g. "models") from
`use crate::models::{User, Repo}` as a spurious NamedImportMap entry.
Skip scoped_identifier nodes that are direct children of scoped_use_list
since they are path prefixes, not importable symbols.
Adds rust-grouped-imports fixture and 4 integration tests verifying both
symbols resolve correctly and no spurious binding leaks through.
|
@magyargergo check these optimizations: The Heritage resolution and Call resolution needs symbol table and import map respectively. So they can be parallelized The MRO scan can benefit from a type-index. It will go from O ( all edges ) to O( inheritance edges ) Also I think we can cache import alias per-chunk since symbol table dont change mid-resolution await processImports(); |
|
@claude review the code and also focus on evaluating the comments above. |
|
Claude finished @magyargergo's task in 6m 22s —— View job Code Review (Updated) + Optimization Evaluation
What Changed Since the Last ReviewTwo commits landed since the previous review (
Both fixes are correctly implemented. One residual limitation noted below. Residual Limitation in
|
…collision Two methods named identically in different classes within the same file previously shared a scope key, causing non-deterministic type resolution. Now keys use funcName@startIndex for uniqueness. Also adds tests documenting destructuring assignment extraction gap.
Merged origin/main (03bfa3c) into feat/method-resolution-order. Conflicts in CLAUDE.md and AGENTS.md were GitNexus index stats — kept our branch's numbers (1747 symbols, 4569 relationships).
Worker path now runs processCallsFromExtracted, processHeritageFromExtracted, and processRoutesFromExtracted via Promise.all instead of sequentially. Safe because all three only read shared state and write via addRelationship's dedup guard. Sequential fallback path stays sequential (shared LRU astCache). Also fixes Rust collectRustBindings spurious path-prefix bindings for 3+ level grouped imports, and adds @param JSDoc for walkBindingChain's allDefs invariant.
Clarify that the parallelization safety comes from disjoint relationship types + idempotent id-keyed Maps, not from lack of shared state (the graph is shared). Strengthen allDefs JSDoc to describe silent-miss consequence of passing pre-filtered results.
Performance & Code Quality UpdatesAddressed remaining review feedback with two focused changes: 1. Parallelize
|
…tables Phase 1: Extract type binding logic from type-env.ts (635→125 LOC) into type-extractors/ directory with per-language files and Record<SupportedLanguages, LanguageTypeConfig> + satisfies dispatch. Phase 2: Extract 5 config loaders from import-processor.ts into language-config.ts (removed ~196 LOC of inline loaders). Phase 3: Convert export-detection.ts switch/case to exhaustive Record<SupportedLanguages, ExportChecker> + satisfies dispatch table, fix node: any → SyntaxNode. Also adds language feature matrix to README. All 1146 unit tests and 433 integration tests pass.
…(Phase 1) Extract per-language type extraction from type-env.ts (635→125 LOC) into type-extractors/ with Record<SupportedLanguages, LanguageTypeConfig> + satisfies dispatch. 9 per-language files, shared helpers, and barrel index.
Move 5 language-specific config loaders and their type interfaces from import-processor.ts into standalone language-config.ts module.
# Conflicts: # gitnexus/src/core/ingestion/import-processor.ts # gitnexus/src/core/ingestion/language-config.ts
|
@claude review my latest changes and focus on the performance characteristics of this PR and how this evolved from the beginning. Include flow diagrams and breakdowns. |
|
Claude finished @magyargergo's task in 3m 25s —— View job Performance Analysis: Evolution of the Resolution Pipeline
Latest Changes (814fac1 + 0227448)The two most recent commits are correct and complete:
One residual note on the Rust fix: The previous How Performance Evolved: The Full StoryThis PR added approximately 13,800 lines across 37 commits. Below is a breakdown of every significant performance and correctness dimension, showing how each evolved from start to finish. 1. Ingestion Pipeline ArchitectureBefore this PR (baseline) After this PR (current) Impact of Promise.all parallelization (814fac1): For a large Java repository with 5,000 files:
The sequential fallback path (used when the worker pool fails) correctly stays sequential because it shares an LRU 2. Symbol Resolution: From O(N) First-Match to Tiered Confidence FilteringThis is the most architecturally significant evolution in the PR. Stage 0 (pre-PR): raw False positives silently produced incorrect edges. Two classes named Stage 1 (d0a29a2 + fcf90dd): 3-Tier resolver, ambiguity refusal This was the foundational correctness improvement: Stage 2 (b7a8db9): NamedImportMap — file-level → name-level precision Before: After: each named binding recorded individually. Resolution logic expanded: Stage 3 (7dbdb5c + 883b041):
Stage 4 (d8c1e1e): Re-export chain resolution (up to 5 hops) Cycle detection via Stage 5 (054a344 + 005ff3a): Full language coverage
Stage 6 (814fac1): Parallelized in pipeline Resolution itself didn't change; it now runs concurrently with heritage and route resolution per chunk. 3. Call Resolution Pipeline: 4-Stage FunnelThe call resolution funnel evolved from a single lookup to a 4-stage filter that progressively narrows candidates: Stage B (arity) was added in 4. TypeEnv: Receiver Type TrackingThe 5. MRO Processor: The One Dropped Optimization
For a large repo, this is O(all edges) when only O(inheritance edges) are needed. The PR considered a type-indexed accessor but dropped it as YAGNI — the comment notes "500K string comparisons is single-digit ms in V8". This is correct at current scale. For a Linux-kernel-sized codebase (millions of edges), this would become the MRO bottleneck. The dropped optimization would have been: // Hypothetical: type-indexed edge accessor
graph.forEachRelationshipOfType(['EXTENDS', 'IMPLEMENTS', 'HAS_METHOD'], (rel) => { ... });
// O(25K) instead of O(500K)6. Memory Architecture: 20MB Chunk BudgetThe chunk budget model ( This means calls to symbols defined in a later chunk are resolved as global fuzzy matches rather than import-scoped matches. For most repos this is a minor accuracy loss. For monorepos where barrel files import from many chunks, it could cause Tier 3 fallback for symbols that should be Tier 2. Performance Characteristics Summary
Remaining Performance Notes
|
…tructor discrimination (abhigyanpatwari#238) * feat: add Method Resolution Order (MRO) with language-specific rules Implement full MRO computation for multi-language inheritance hierarchies: - HAS_METHOD edges: Class→Method ownership edges emitted during parsing (both worker pool and sequential fallback paths) - Method signatures: extract parameterCount and returnType from AST nodes - C# heritage fix: distinguish EXTENDS vs IMPLEMENTS for base_list captures using symbol table lookup + I[A-Z] naming heuristic fallback - MRO processor (Phase 4.5): walks inheritance DAG, detects method-name collisions across parents, applies language-specific resolution: - C++: leftmost base class in declaration order wins - C#/Java: class method wins over interface default - Python: C3 linearization with cycle detection - Rust: no auto-resolution (requires qualified syntax) - Default: first definition in BFS order wins - OVERRIDES edges emitted for resolved method collisions - KuzuDB schema: Method table extended with parameterCount/returnType; dedicated CSV writer and COPY query for 10-column Method rows - MCP tools: updated Cypher examples for HAS_METHOD, OVERRIDES, diamond 72 tests across 5 test files covering MRO resolution, HAS_METHOD edges, method signature extraction, C# heritage resolution, and integration tests across C#/Rust/Python/TS/Java/C++. * feat: add scope-based symbol resolution replacing raw lookupFuzzy Introduces a shared 3-tier resolveSymbol function used by both heritage-processor and call-processor: 1. Same-file (lookupExactFull — authoritative) 2. Import-scoped (filtered by ImportMap — high confidence) 3. Global fuzzy (first match — low confidence fallback) Adds lookupExactFull to SymbolTable returning full SymbolDefinition with type info needed for heritage Class/Interface disambiguation. * refactor: tighten symbol resolution — Tier 3 refuses ambiguous matches - lookupExactFull now O(1) via direct SymbolDefinition storage in fileIndex (shared object references with globalIndex — zero additional memory) - Added resolveSymbolInternal() preserving { definition, tier, candidateCount } for test assertions and logging - Tier 3 now returns null when multiple global candidates exist instead of arbitrary allDefs[0] — a wrong edge is worse than no edge - call-processor: renamed fuzzy-global → unique-global, removed dead branch - 12 new tests: tier assertions, ambiguous refusal per language family, heritage false-positive guard, O(1) shared reference verification * fix: critical language support bugs in import resolution and MRO Phase 5 critical fixes from all-language analysis: - Python: add relative_import query capture (PEP 328) — `.models`, `..utils` were silently dropped, producing zero ImportMap entries - Rust: extract prefix from grouped imports `crate::module::{A, B}` — brace groups previously failed resolution entirely - Swift: use normalizedFileList for Windows path compatibility in module import resolution (matches Go's resolveGoPackage pattern) - MRO: fix c_sharp → csharp language name mismatch (enum is 'csharp'), add Kotlin to C#/Java resolution rules (class method wins over interface) * feat: add strict multi-language integration tests + fix C/C++ import resolution Add 32 integration tests across 6 language fixtures (TypeScript, C#, C++, Java, Python, Rust) with exact toBe/toEqual assertions validating heritage edges, import resolution, and trait implementations. Fix C/C++ import resolution bug where dot-to-slash conversion mangled include paths (e.g. "animal.h" became "animal/h"). Now skips conversion for C/C++ languages which use actual file paths in #include directives. * fix: language-gate heritage heuristic, add Swift extension heritage, handle Rust grouped imports - Gate I[A-Z] naming heuristic to C#/Java only (was firing for all languages) - Swift unresolved types default to IMPLEMENTS (protocol conformance is the norm) - Add tree-sitter query for Swift extension protocol conformance (extension Foo: Protocol) - Handle Rust top-level grouped imports (use {crate::a, crate::b}) in both import loops - Add 4 new heritage-processor tests (TypeScript refusal, Swift default, Swift Tier 1) * feat: add Go struct embedding heritage + PackageMap optimization Add Go struct embedding detection (anonymous fields → EXTENDS edges) via new tree-sitter heritage query with named-field filtering in both parse-worker and heritage-processor paths. Implement PackageMap optimization for Go cross-package resolution: replace O(N) file-level ImportMap expansion with directory-level suffix matching (Tier 2b in symbol resolver). Graph IMPORTS edges are preserved via addImportGraphEdge split. Remove overly broad @definition.type from GO_QUERIES that was double-matching structs/interfaces as TypeAlias nodes, breaking Tier 3 unique-global resolution. Add Go fixture (go-pkg) with Admin→User embedding, cross-package calls, and 7 integration tests covering structs, functions, imports, calls, and heritage edges. * test: add Kotlin heritage integration tests Adds a kotlin-heritage fixture and 7 integration tests validating class inheritance, interface implementation, JVM-style import resolution, and symbol-table-driven EXTENDS/IMPLEMENTS disambiguation via Kotlin delegation specifiers. * feat: extract resolvers, add PHP tests, ambiguous tests for all languages - Extract language-specific resolvers from import-processor.ts into resolvers/ directory (P7): jvm, go, csharp, php, rust, standard, utils - import-processor.ts reduced from 1412 to 711 lines (50% reduction) - Add comprehensive PHP integration tests: PSR-4 imports, traits, enums, heritage edges, method calls, MRO overrides - Add ambiguous symbol resolution tests for all 9 languages verifying correct disambiguation via import chains - Split monolithic lang-resolution.test.ts (1080 lines) into 9 per-language files under test/integration/resolvers/ with shared helpers * feat: update integration tests to include resolver tests for multiple languages * fix: address code review — schema gap, Rust impl name, Property OVERRIDES Bugs fixed: - Add 13 missing FROM/TO pairs in RELATION_SCHEMA for HAS_METHOD edges (Class/Interface/Struct/Trait/Impl/Record to Method/Constructor/Property) - Fix findEnclosingClassId to pick implementing type for Rust impl Trait for Struct blocks (was picking trait name) - Exclude Property nodes from MRO OVERRIDES collision detection - Change MRO language fallback from typescript to unknown Tests added: - Unit: Property OVERRIDES exclusion (2 tests), Rust impl Trait for Struct name resolution (2 tests), schema HAS_METHOD pair coverage - Integration: no OVERRIDES targets Property nodes across all 9 languages - PHP fixture: added shared $status property to both traits to create real collision scenario for Property OVERRIDES exclusion test Documentation: - OVERRIDES edge direction (Class to Method), Go return type gap, BFS first-reach heuristic limitation * feat: harden CALLS-edge resolution — Phase 0 validation - Fix same-file confidence (0.85 → 0.95) to correctly outrank import-scoped (0.9) - Fix Tier 1 overload preservation: use globalIndex filter instead of fileIndex lookup - Add callable-kind guard: refuse CALLS edges to Interface and Enum symbols - Fix Kotlin countCallArguments: handle call_suffix → value_arguments nesting - Fix Kotlin extractFunctionName: add simple_identifier to fallback search - Strictly type findParameterList and countCallArguments (remove all `any`) - Add arity-based call resolution integration tests for 9 languages - Add unit regression tests for Interface/Enum CALLS refusal * chore: remove C# build artifacts from fixtures * feat: add call-form discrimination and ownerId to symbol table (Phase 1) Add inferCallForm() and extractReceiverName() to distinguish free/member/constructor calls at the AST level across all 9 languages. Add ownerId field to SymbolDefinition linking Method/Constructor/Property to their owning class. Includes 36 unit tests and member-call integration tests for all 9 languages (132 tests, 0 failures). * feat: constructor/struct-literal resolution across all languages (Phase 2) Add constructor discrimination to CALLS-edge resolution: new Foo(), User{...} struct literals, and C# primary constructors now resolve to Constructor/Class/Struct/Record nodes instead of being filtered out. Queries: new_expression (C++), object_creation_expression (PHP), composite_literal (Go), struct_expression (Rust), primary constructor and implicit_object_creation_expression (C#). Relaxes global tier in collectTieredCandidates to pass all candidates through filterCallableCandidates, allowing kind/arity narrowing to disambiguate at lower confidence. * feat: receiver-constrained resolution with integration tests for all 9 languages Add receiver-type filtering (Phase 3): when a member call like `user.save()` has a known receiver type from TypeEnv, filter candidates by ownerId to disambiguate methods with the same name across different classes. Key changes: - call-processor: build per-file TypeEnv, pass receiverTypeName to resolveCallTarget - parse-worker: extract receiverTypeName from TypeEnv in worker thread - resolveCallTarget: new step D filters by ownerId matching receiver type - utils: extractReceiverName supports C++ field_expression (argument field) - utils: findEnclosingClassId extracts Go method receiver types - type-env: handle Go qualified_type, Kotlin user_type/variable_declaration - parse-worker + parsing-processor: Function added to needsOwner for Kotlin/Rust/Python class methods captured as Function nodes Integration tests added for receiver-constrained resolution across all 9 languages: TypeScript, Java, Python, Go, Rust, C++, C#, Kotlin, PHP. * feat: NamedImportMap, scoped TypeEnv, broadened signatures + TS rest-param variadic fix Address all 4 PR abhigyanpatwari#238 review items: 1. Remove redundant lookupFuzzy in processRoutesFromExtracted 2. Add NamedImportMap for TS/Python symbol-level import tracking (Tier 2a) 3. Make TypeEnv scope-aware (Map<scopeKey, Map<varName, type>>) to fix non-deterministic receiver resolution across functions 4. Broaden extractMethodSignature: Go/Rust/C++ return types, variadic detection for Go/Java/Python/C++/Kotlin/TypeScript rest params Discovered and fixed: TS rest params (...args) were not detected as variadic — added rest_pattern detection inside required_parameter nodes. Integration tests added: scoped receiver, named import disambiguation, and variadic call resolution for both TypeScript and Python. * fix: alias import resolution, Go multi-assign TypeEnv, dead code removal - NamedImportMap now stores {sourcePath, exportedName} so aliased imports (import { User as U }) resolve U → User in the source file - Named binding check moved before empty-allDefs early return in both call-processor and symbol-resolver, fixing constructor calls via aliases - Go extractFromGoShortVarDeclaration iterates all LHS/RHS pairs for multi-assignment (user, repo := User{}, Repo{}) instead of only first - Remove unused TYPED_DECLARATION_TYPES set (TYPED_PARAMETER_TYPES kept) - Integration tests for both fixes (go-multi-assign, typescript-alias-imports) * feat: alias import extraction for Kotlin, Rust, PHP, C# + integration tests Add named import alias extraction to both pipeline paths (import-processor.ts and parse-worker.ts) for Kotlin, Rust, PHP, and C#. Add integration test fixtures and tests for all 5 languages (Python alias extraction already worked, just needed the test). Each test verifies: class detection, member call resolution through aliases to correct target files, and IMPORTS edge emission. * refactor: use SupportedLanguages enum everywhere instead of raw strings Replace all raw language string literals and `language: string` types with the SupportedLanguages enum across 10 files. This ensures compile-time safety for language dispatch and eliminates dead `language === 'tsx'` checks (tsx maps to TypeScript in the enum). * fix: tier-ordering bug, re-export chains, PHP grouped imports, Java named imports - Fix collectTieredCandidates tier-ordering: same-file now checked before named bindings, preventing imports from shadowing local definitions (matches resolveSymbolInternal priority order) - Add re-export chain resolution for TypeScript/JavaScript barrel files: export { X } from './base' and export type { X } from './base' now followed up to 5 hops through NamedImportMap - Fix PHP grouped import alias extraction: use App\Models\{User, Repo as R} now correctly handled in both parse-worker and import-processor - Add Java NamedImportMap support: import com.example.models.User now records User as a named binding for precise disambiguation - Add 16 new integration tests across TypeScript, PHP, and Java resolvers (220 total resolver tests, all passing) * refactor: consolidate alias extraction + add variadic/constructor/shadow integration tests - Extract shared named-binding-extraction.ts from duplicate logic in import-processor.ts and parse-worker.ts (net -200 lines) - Deduplicate appendKotlinWildcard (now imported from resolvers/index.ts) - Add integration tests: constructor calls (Kotlin, Python), variadic resolution (Go, Java, C#, C++, Kotlin), re-export chains (Python), local definition shadowing (Python, Go) - Add TODO(stack-graph) for TypeEnv scope key collision - 225 integration tests passing (was 223) * fix: PHP non-aliased imports, Python node identity, re-export chain dedup + local-shadow tests - PHP flat non-aliased imports (use App\Models\User) now stored in NamedImportMap - PHP grouped non-aliased imports ({User} in {User, Repo as R}) now stored in NamedImportMap - Python: replace non-public child.id with child.startIndex for node identity - Extract shared walkBindingChain() from symbol-resolver and call-processor - Add PHP variadic resolution fixture + test (variadic_parameter already covers PHP) - Add local-shadow integration tests for Java, C#, Kotlin, Rust, PHP, C++ (6 languages) * feat: Rust non-aliased use bindings, Kotlin non-aliased imports, re-export chain resolution Extend NamedImportMap coverage for Rust and Kotlin non-aliased imports: - Rust: rename collectUseAsClauses → collectRustBindings, extract terminal scoped_identifier (use crate::models::User) and identifier in use_list (use crate::models::{User, Repo}) into NamedImportMap. This also enables pub use re-export chain following via walkBindingChain. - Kotlin: extend extractKotlinNamedBindings to handle non-aliased imports (import com.example.User), skipping wildcard imports. - Add rust-reexport-chain fixture + 3 integration tests verifying Handler{} resolves through mod.rs pub use to handler.rs. - Add Kotlin heritage + constructor-calls reason assertions for non-aliased import-resolved resolution. - Add C# heritage test documenting namespace import tier behavior. * fix: skip Kotlin lowercase member imports in NamedImportMap Member imports like `import util.OneArg.writeAudit` (lowercase last segment) must not populate NamedImportMap — same-named function imports from different classes collide, breaking arity-based disambiguation. Apply the same guard Java already uses: skip lowercase last segments. * fix: skip spurious path-prefix bindings in Rust grouped imports collectRustBindings was extracting the path segment (e.g. "models") from `use crate::models::{User, Repo}` as a spurious NamedImportMap entry. Skip scoped_identifier nodes that are direct children of scoped_use_list since they are path prefixes, not importable symbols. Adds rust-grouped-imports fixture and 4 integration tests verifying both symbols resolve correctly and no spurious binding leaks through. * fix: use startIndex in TypeEnv scope key to prevent same-name method collision Two methods named identically in different classes within the same file previously shared a scope key, causing non-deterministic type resolution. Now keys use funcName@startIndex for uniqueness. Also adds tests documenting destructuring assignment extraction gap. * test: document C# namespace-level import limitation in named binding extraction * test: document same-arity overload discrimination limitation in call processor * perf: parallelize calls/heritage/routes processing in worker path Worker path now runs processCallsFromExtracted, processHeritageFromExtracted, and processRoutesFromExtracted via Promise.all instead of sequentially. Safe because all three only read shared state and write via addRelationship's dedup guard. Sequential fallback path stays sequential (shared LRU astCache). Also fixes Rust collectRustBindings spurious path-prefix bindings for 3+ level grouped imports, and adds @param JSDoc for walkBindingChain's allDefs invariant. * docs: improve Promise.all safety comment and walkBindingChain JSDoc Clarify that the parallelization safety comes from disjoint relationship types + idempotent id-keyed Maps, not from lack of shared state (the graph is shared). Strengthen allDefs JSDoc to describe silent-miss consequence of passing pre-filtered results. * refactor: extract language-specific processing into modular dispatch tables Phase 1: Extract type binding logic from type-env.ts (635→125 LOC) into type-extractors/ directory with per-language files and Record<SupportedLanguages, LanguageTypeConfig> + satisfies dispatch. Phase 2: Extract 5 config loaders from import-processor.ts into language-config.ts (removed ~196 LOC of inline loaders). Phase 3: Convert export-detection.ts switch/case to exhaustive Record<SupportedLanguages, ExportChecker> + satisfies dispatch table, fix node: any → SyntaxNode. Also adds language feature matrix to README. All 1146 unit tests and 433 integration tests pass. * refactor: extract type binding logic into type-extractors/ directory (Phase 1) Extract per-language type extraction from type-env.ts (635→125 LOC) into type-extractors/ with Record<SupportedLanguages, LanguageTypeConfig> + satisfies dispatch. 9 per-language files, shared helpers, and barrel index. * refactor: extract config loaders to language-config.ts (Phase 2) Move 5 language-specific config loaders and their type interfaces from import-processor.ts into standalone language-config.ts module.

Summary
This PR builds a language-aware code intelligence engine -- the core of an LSP-grade symbol resolver that understands imports, inheritance, method ownership, constructor patterns, receiver-typed member calls, and call-site semantics across 9 languages.
Symbol Resolution Engine
callFormfield distinguishes regular calls, member calls (obj.method()), and constructor calls (new Foo()/ struct literals) -- each form gets different candidate filteringownerIdmatching the resolved receiver type -- disambiguatesuser.save()vsrepo.save()when bothUserandRepohavesave()methodsReceiver-Constrained Resolution (Phase 3)
Map<string, string>built from explicit type annotations (let x: T,T x,x: T,var x models.T, typed params)ownerIdmatching resolved receiver type nodeIdfindEnclosingClassIdextracts receiver type frommethod_declaration(e.g.,func (u *User) Save()-> User struct)Constructor & Struct Literal Resolution
new Foo()resolves to Constructor > Class (TS, Java, C#, C++, PHP, Kotlin)User{...}in Go,User { ... }in Rust) resolve to Struct nodesclass User(string name, int age)) emit Constructor nodes with correctparameterCountUser u = new("x")) extracts type from variable declarationMethod Resolution Order (MRO)
OVERRIDESedges when inherited methods collide (never targets Property nodes)Heritage & Ownership
parameterCountandreturnTypeextracted for Method/Constructor nodesEXTENDSedges for embedded structs +PackageMapoptimizationuse crate::{models, other}correctly expandedResolver Architecture
resolvers/directory (JVM, Go, C#, PHP, Rust, standard, utils)import-processor.tsreduced from 1412 -> 711 lines (50% reduction)Bug Fixes
resolveImportPathno longer mangles#includepathsbase_listdistinguishes EXTENDS vs IMPLEMENTS via symbol table +I[A-Z]heuristicqualified_type(models.User) correctly unwrapped in TypeEnvuser_typewrapper andvariable_declarationnesting handled in TypeEnvfield_expressionreceiver extraction viaargumentfieldSchema
parameterCount INT32,returnType STRINGTest plan
Integration tests -- 9 languages (
test/integration/resolvers/)Unit tests
Stats