Repository navigation
feat(server): index-based declaration, implementation and typeDefinition - #480
Conversation
resolve_cursor bailed out without a session, so every index query on a closed document returned empty. The merged shard stores the file content already — use its own line map for position mapping when no session exists.
Replace the null stubs with index queries. Implementation and typeDefinition resolve between-symbol relations through the new two-hop Indexer::query_symbol_targets (relation target hash -> definition location). Declaration returns declarations plus the definition, so inline-defined symbols still navigate. Unit tests lock the relation directions and the known type-relation gaps (auto deduction, alias unwrapping).
references: includeDeclaration now includes declarations as well as definitions, and empty results return [] per the error-feedback convention. E2E coverage: cross-file declaration, inline-definition declaration, override-chain implementation, typeDefinition, and the includeDeclaration flag, on a new nav.h/nav.cpp fixture.
Closed documents are index-serveable: empty navigation results return [] instead of a Document-not-open error (review finding — an error would surface as an editor popup for a legitimate no-results answer). Adds pure-virtual and chained-override implementation, forward-declaration navigation, exact-set references assertions, the open/closed empty contract, and locks the missing return-type TypeDefinition relation as a recorded index gap.
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
📝 WalkthroughWalkthroughAdds an index-backed ChangesIndex-only navigation feature
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Client
participant LspClientHandler
participant Indexer
participant Shard
Client->>LspClientHandler: textDocument/declaration or implementation or typeDefinition
LspClientHandler->>LspClientHandler: query_targets_at(uri, position, kind)
LspClientHandler->>Indexer: query_symbol_targets(path, position, kind, session)
Indexer->>Indexer: resolve_cursor(position, session)
Indexer->>Shard: to_offset(position) via session or shard content
Indexer->>Indexer: collect target symbol hashes for RelationKind
Indexer->>Indexer: resolve_symbol(target hash) per target
Indexer-->>LspClientHandler: protocol::Location list
LspClientHandler-->>Client: locations or empty array
PoemA rabbit hops through symbol trees, 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
tests/integration/features/test_index.py (1)
380-391: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winConsider asserting no duplicate locations.
This test only checks membership (
in), so it wouldn't catch a duplicate("nav.h", 6)entry if the declaration handler returns the record's definition site twice (see companion comment inlsp_client.cpp). Assertinglen(locs) == len(set(lines))or exact set equality would make this test also guard against that regression.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@tests/integration/features/test_index.py` around lines 380 - 391, The declaration lookup test for test_goto_declaration_forward_declared only checks that expected locations are present, so it can miss duplicate results from client.declaration_at. Update the assertions in this test to validate uniqueness as well, using the existing locs/lines data from locations_of so that a repeated nav.h definition entry is caught, ideally by asserting exact set equality or by comparing len(locs) to the number of unique lines.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@tests/integration/features/test_index.py`:
- Around line 380-391: The declaration lookup test for
test_goto_declaration_forward_declared only checks that expected locations are
present, so it can miss duplicate results from client.declaration_at. Update the
assertions in this test to validate uniqueness as well, using the existing
locs/lines data from locations_of so that a repeated nav.h definition entry is
caught, ideally by asserting exact set equality or by comparing len(locs) to the
number of unique lines.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: feb5b762-7bed-4122-b24b-af0788bdefa9
📒 Files selected for processing (10)
docs/en/features/navigation.mdsrc/server/compiler/indexer.cppsrc/server/compiler/indexer.hsrc/server/service/lsp_client.cpptests/data/index_features/CMakeLists.txttests/data/index_features/nav.cpptests/data/index_features/nav.htests/integration/features/test_index.pytests/integration/utils/client.pytests/unit/index/index_query_tests.cpp
Background
textDocument/declaration,implementationandtypeDefinitionwere advertised in the initialize capabilities but their handlers returned null stubs; find-references worked but returnednullfor empty results and only merged definitions underincludeDeclaration. This PR completes the index-based navigation set.Implementation
Indexer::query_symbol_targets): resolve the cursor to a symbol, collect between-symbol relation targets (Implementation,TypeDefinition), then resolve each target hash to its definition location — the same machinery type hierarchy already uses. Relation directions are locked by unit tests: a base virtual method'sImplementationrelations point at its direct overrides; each level of a deep override chain navigates to its own overriders.Declarationrelation, and navigating to the definition is what clients expect there.includeDeclarationnow includes declarations as well as definitions; empty results return[].resolve_cursorpreviously bailed without a session, so every index query on a closed file returned empty — it now maps positions through the merged shard's own stored content. Navigation on closed documents works, and an empty result is a real answer ([]), never an error.All three new methods are index-only by design: no worker fallback (go-to-definition's worker fallback already covers the fresh-buffer path that matters).
Recorded index gaps (deliberately not fixed here)
Locked by tests so future indexer fixes surface as intentional test updates:
auto-deduced variables carry noTypeDefinitionrelation; alias-typed variables navigate to theusingdeclaration instead of unwrapping.TypeDefinitionrelation for their return type.Tests
ImplementationDirection,TypeDefinitionTargets) on the index query harness.nav.h/nav.cppfixture: cross-file declaration, inline-definition declaration, forward-declaration navigation, virtual override and pure-virtual implementation, chained-override direct-only semantics, typeDefinition, references with exact-set assertions for bothincludeDeclarationmodes, and the open/closed empty-result contract.Test plan
pixi run formatclean; 3 parallel review subagents (correctness / style / tests) — findings addressed