Implements support for the enclosing_range field in SCIP occurrences,#504
Implements support for the enclosing_range field in SCIP occurrences,#504simonhollis wants to merge 1 commit into
enclosing_range field in SCIP occurrences,#504Conversation
enabling IDE features like: - Call hierarchies (determining symbol references within function bodies) - Symbol outline/breadcrumbs (showing path from cursor to file root) - Expand selection (selecting nearest enclosing AST node) - Highlight range (indicating AST expression boundaries for hovers) ## Changes ### 1. Updated SCIP Dependency Updated to SCIP commit `9d5796159c97c3b107355c424f6c06fb1a0ea01c` which includes: - The `enclosing_range` field definition in the protobuf schema - The `add_enclosing_range()` API for populating individual values ### 2. Extended Indexer API Added `clang::SourceRange enclosingRange` parameter (with default empty value) to: - `TuIndexer::saveDefinition()` - `TuIndexer::saveReference()` - `TuIndexer::saveOccurrence()` - `TuIndexer::saveOccurrenceImpl()` ### 3. Implemented Range Population Modified `saveOccurrenceImpl()` to populate the `enclosing_range` field: - Format: `[startLine-1, startColumn-1, [endLine-1], endColumn-1]` - Uses 0-based coordinates as per SCIP specification - Omits endLine if range is single-line - Only populates when valid range is provided
|
Hi! Thank you for the contribution. Can you please regenerate test snapshots with your changes? |
|
Adding a concrete downstream use case in support of this PR. I'm building a call graph for C++ from scip-clang indexes. To draw a "function A calls function B" edge, I need to know which function body each reference sits inside. scip-clang gives the line of every occurrence, but not the start/end of each function body — so the only fallback is a heuristic: attribute a reference to the nearest preceding definition. That heuristic misattributes any reference that lives in a class body instead of a function body. The clearest case is a member's own in-class declaration, which gets counted as a "call" from the method declared just above it: class Mutex {
void lock() { /* ... */ } // a definition
void _lock(); // just a declaration — misread as a call from lock()
};I can't disambiguate this consumer-side: an in-class declaration So this PR would enable correct C++ call graphs, beyond the IDE features listed. #323 was closed as not planned, but for code-intelligence consumers this field is really the line between an approximate and an exact call graph. Thanks for picking it up. |
…ng limit Investigated the nearest-preceding-definition misattribution: proven not refinable with scip-clang v0.4.0 (in-class declaration vs genuine inline-body call are structurally identical; every suppression rule drops 15-20% genuine edges). Kept as safe-direction over-capture. Clean fix needs enclosing_range, blocked on upstream PR sourcegraph/scip-clang#504.
| if (enclosingRange.isValid() && begin.isValid() && end.isValid() | ||
| && begin != end && begin < end) { |
There was a problem hiding this comment.
Testing this PR, workers crash on many TUs with:
Indexer.cc: enforced condition sourceManager.getFileID(end) == fileId ... range should not be split across files
saveOccurrence passes enclosingRange to FileLocalSourceRange::fromNonEmpty, which ENFORCEs both endpoints share a FileID, but an enclosing range can span a macro expansion or #include boundary, so the ENFORCE trips and kills the worker.
The crashed workers don't recover: the driver logs timeout: no workers have responded yet and terminating worker … due to worker timeout, respawns them, they crash again. On one full index this ran ~2.5h with 205 crashes and 197 worker-timeout terminations, and no .scip was ever produced (the run doesn't error out, it just never finishes).
Fix: add a same-file guard to the condition and skip enclosing_range otherwise (it's optional):
if (enclosingRange.isValid() && begin.isValid() && end.isValid()
&& begin != end && begin < end
&& sourceManager.getFileID(begin) == sourceManager.getFileID(end)) {With this guard: 0 crashes over a full index.
Summary
Implements support for the
enclosing_rangefield in SCIP occurrences, enabling IDE features like:Changes
1. Updated SCIP Dependency
Updated schema to SCIP commit
9d5796159c97c3b107355c424f6c06fb1a0ea01cwhich includes:
enclosing_rangefield definition in the protobuf schemaadd_enclosing_range()API for populating individual values2. Extended Indexer API
Added
clang::SourceRange enclosingRangeparameter (with defaultempty value) to:
TuIndexer::saveDefinition()TuIndexer::saveReference()TuIndexer::saveOccurrence()TuIndexer::saveOccurrenceImpl()3. Implemented Range Population
Modified
saveOccurrenceImpl()to populate theenclosing_rangefield:
[startLine-1, startColumn-1, [endLine-1], endColumn-1]