Unnamed repository; edit this file 'description' to name the repository.
Merge pull request #21141 from Wilfred/scip_enclosing_range
feature: Set enclosing_range field on SCIP output
| -rw-r--r-- | crates/ide/src/static_index.rs | 12 | ||||
| -rw-r--r-- | crates/rust-analyzer/src/cli/scip.rs | 38 |
2 files changed, 49 insertions, 1 deletions
diff --git a/crates/ide/src/static_index.rs b/crates/ide/src/static_index.rs index 052de0f38e..52b201df96 100644 --- a/crates/ide/src/static_index.rs +++ b/crates/ide/src/static_index.rs @@ -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 @@ impl StaticIndex<'_> { 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 diff --git a/crates/rust-analyzer/src/cli/scip.rs b/crates/rust-analyzer/src/cli/scip.rs index 37f83f6dee..f822efb53d 100644 --- a/crates/rust-analyzer/src/cli/scip.rs +++ b/crates/rust-analyzer/src/cli/scip.rs @@ -189,6 +189,13 @@ impl flags::Scip { 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 @@ impl flags::Scip { 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 @@ pub mod example_mod { 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)); + } } |