fix: SCIP symbol-name and enrichment correctness (parameter descriptor pollution, span/name/enrichment) - #40
Open
pradeepmouli wants to merge 3 commits into
Conversation
SCIP symbols end with a descriptor suffix (`.`, `#`, `/`, `:`, or a method disambiguator) as the literal last character, e.g. `rust-analyzer cargo sittir-core 0.0.0 crate/` or `...main().`. The old implementation rsplit on those same suffix chars *without stripping the trailing one first*, so it always read the segment after the last delimiter -- which is empty when the delimiter is the last byte. Verified against a real rust-analyzer SCIP index of sittir: 22,075 of 28,861 non-local symbols (76%) resolved to an empty name. Every empty name causes import_scip_index to miss matching the existing tree-sitter symbol and instead insert a duplicate placeholder node, and collisions on the shared (file, "") key make CALLS/enrichment resolution pick an arbitrary same-file symbol instead of the real target. Also verified against scip-typescript output (22,028 symbols, 0 empty names after the fix). Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TAXDJyFdnA4BV1U2fxufdC # Conflicts: # crates/infigraph-core/src/scip/mod.rs
…e/end_line SCIP enrichment's UNWIND SET was writing a Definition occurrence's range (the identifier token's own span) into an existing symbol's start_line/ end_line, clobbering tree-sitter's correct full-body span. Any symbol SCIP successfully re-matches during enrichment -- the default, common-case path, not an edge case -- had its displayed source silently collapsed to ~1 line afterward, degrading get_doc_context/get_code_snippet output broadly for any SCIP-enriched project. Root cause: SCIP definition-occurrence ranges are the identifier token's position, not the enclosing declaration's extent. enrichments now only carries (id, docstring); start_line/end_line are left untouched for existing symbols, matching what tree-sitter already computed correctly. New symbols added purely from SCIP (no tree-sitter counterpart) are unaffected by this fix and keep using SCIP's span, since they have no better source. Regression test: enrichment_does_not_overwrite_existing_symbol_span reproduces the exact bug (pre-fix: start_line collapses to the token line) and asserts the full-body span survives enrichment. Confirmed live on this repo: crates/infigraph-core/src/embed/mod.rs:: update_embeddings had regressed to a single-line "source" (L444-444) after ordinary SCIP enrichment; a fresh index + rebuild after this fix restores its correct ~83-line span. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GhPBkDMHPpgcYJ3TKLAC1r # Conflicts: # crates/infigraph-core/src/scip/mod.rs
…ymbols get_doc_context on SCIP-enriched (scip-typescript) TypeScript projects showed raw, unparsed SCIP monikers as caller/callee entries -- one per function parameter. Root cause: scip-typescript encodes parameters as a full global-style moniker (<method>().(paramName)) rather than a SCIP-spec `local <id>` symbol, so the existing local-symbol filter missed them, and every parameter became its own bogus Symbol node (each with a tiny declaration-line span that could also steal container_id from real references via the smallest-span-first containment lookup). Fixed by recognizing this structurally rather than by SCIP kind (verified always UnspecifiedKind in real output, unusable) or by re-parsing with tree-sitter (would need per-language node-kind tables across all 10 configured SCIP indexers): a parameter's moniker is exactly its enclosing method's own already-known moniker with `(paramName)` appended, so stripping the trailing group and checking against scip_sym_to_file_name (already built before this decision runs) exactly identifies membership without any new data or heuristics.
pradeepmouli
requested review from
johnintuit,
murari316 and
sandeep-mewara
as code owners
July 29, 2026 18:06
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Three related fixes to SCIP import correctness in
crates/infigraph-core/src/scip/mod.rs, found while investigating spurious/ugly entries inget_doc_contextoutput:scip_sym_to_namereturned empty/wrong names for most real SCIP symbols. The old implementation split on suffix characters (.,#,/,:) without first stripping the trailing suffix marker itself, so it frequently returned an empty string or included the marker. Rewritten to strip the trailing terminator/disambiguator group first, then extract the name, with explicit handling for backtick-quoted descriptors (`test.ts`/Animal#) and bare identifiers.SCIP enrichment overwrote existing symbols'
start_line/end_line. A SCIP definition occurrence's range is the span of the identifier token itself, not the enclosing declaration — but enrichment was writing that narrow range back over the existing symbol's correct full-body span (already established by tree-sitter's AST extraction), silently collapsing every enriched symbol's displayed source to ~1 line. Enrichment now only ever updatesdocstring.Parameter/member descriptors were becoming spurious top-level graph symbols. A simple function parameter's SCIP moniker is
<enclosing-method-moniker-ending-in-.>.(paramName)— nolocalprefix, so it bypassed the existing local-symbol filter and was created as its own (incorrectly named, since it depends on fix Readme Updates and GitHub Pages documentation site #1) graph node. Root-caused against real@sourcegraph/scip-typescript0.4.0 output;SymbolInformation.kindwas verified to always beUnspecifiedKindin real output, so akind-based filter wasn't viable. Fixed with a structural check (is_member_of_known_symbol) that strips a trailing(...)descriptor group and checks whether what remains is already a known symbol from this same import pass — this exploits SCIP's own Parameter-descriptor grammar directly, so it should generalize across every SCIP indexer, not just TypeScript's.Each fix is independently tested; #3 was verified to not affect CALLS-edge resolution (Pass 2) or INHERITS-edge resolution via relationships (Pass 3) — traced through both passes to confirm a suppressed parameter symbol cleanly fails to resolve as a reference target rather than dangling or misattributing an edge.
Test plan
cargo test -p infigraph-core --lib scip::— 7/7 pass (all new + pre-existing tests)cargo fmt --all -- --check— cleancargo clippy -p infigraph-core --all-targets -- -D warnings— clean🤖 Generated with Claude Code