Merge pull request #21141 from Wilfred/scip_enclosing_range

feature: Set enclosing_range field on SCIP output
This commit is contained in:
Chayim Refael Friedman
2025-11-28 03:09:50 +00:00
committed by GitHub
2 changed files with 49 additions and 1 deletions
@@ -44,7 +44,15 @@ pub struct ReferenceData {
pub struct TokenStaticData {
pub documentation: Option<Documentation>,
pub hover: Option<HoverResult>,
/// The position of the token itself.
///
/// For example, in `fn foo() {}` this is the position of `foo`.
pub definition: Option<FileRange>,
/// The position of the entire definition that this token belongs to.
///
/// For example, in `fn foo() {}` this is the position from `fn`
/// to the closing brace.
pub definition_body: Option<FileRange>,
pub references: Vec<ReferenceData>,
pub moniker: Option<MonikerResult>,
pub display_name: Option<String>,
@@ -248,6 +256,10 @@ fn add_file(&mut self, file_id: FileId) {
definition: def.try_to_nav(&sema).map(UpmappingResult::call_site).map(|it| {
FileRange { file_id: it.file_id, range: it.focus_or_full_range() }
}),
definition_body: def
.try_to_nav(&sema)
.map(UpmappingResult::call_site)
.map(|it| FileRange { file_id: it.file_id, range: it.full_range }),
references: vec![],
moniker: current_crate.and_then(|cc| def_to_moniker(self.db, def, cc)),
display_name: def
@@ -189,6 +189,13 @@ pub fn run(self) -> anyhow::Result<()> {
symbol_roles |= scip_types::SymbolRole::Definition as i32;
}
let enclosing_range = match token.definition_body {
Some(def_body) if def_body.file_id == file_id => {
text_range_to_scip_range(&line_index, def_body.range)
}
_ => Vec::new(),
};
occurrences.push(scip_types::Occurrence {
range: text_range_to_scip_range(&line_index, text_range),
symbol,
@@ -197,7 +204,7 @@ pub fn run(self) -> anyhow::Result<()> {
syntax_kind: Default::default(),
diagnostics: Vec::new(),
special_fields: Default::default(),
enclosing_range: Vec::new(),
enclosing_range,
});
}
@@ -508,6 +515,7 @@ fn moniker_descriptors(identifier: &MonikerIdentifier) -> Vec<scip_types::Descri
#[cfg(test)]
mod test {
use super::*;
use hir::FileRangeWrapper;
use ide::{FilePosition, TextSize};
use test_fixture::ChangeFixture;
use vfs::VfsPath;
@@ -887,4 +895,32 @@ fn documentation_matches_doc_comment() {
assert_eq!(token.documentation.as_ref().map(|d| d.as_str()), Some("foo"));
}
#[test]
fn function_has_enclosing_range() {
let s = "fn foo() {}";
let mut host = AnalysisHost::default();
let change_fixture = ChangeFixture::parse(host.raw_database(), s);
host.raw_database_mut().apply_change(change_fixture.change);
let analysis = host.analysis();
let si = StaticIndex::compute(
&analysis,
VendoredLibrariesConfig::Included {
workspace_root: &VfsPath::new_virtual_path("/workspace".to_owned()),
},
);
let file = si.files.first().unwrap();
let (_, token_id) = file.tokens.get(1).unwrap(); // first token is file module, second is `foo`
let token = si.tokens.get(*token_id).unwrap();
let expected_range = FileRangeWrapper {
file_id: FileId::from_raw(0),
range: TextRange::new(0.into(), 11.into()),
};
assert_eq!(token.definition_body, Some(expected_range));
}
}