From 3118122e22c17b1d48a86fd72e01d3c02c539a68 Mon Sep 17 00:00:00 2001 From: Marek Kaput Date: Tue, 14 Jan 2025 12:04:52 +0100 Subject: [PATCH] Optimise variable references search by narrowing down search scopes commit-id:7a9a25c2 --- src/lang/inspect/defs.rs | 32 +++++++++++++++++++------ src/lang/inspect/usages/search_scope.rs | 10 ++++++++ 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/lang/inspect/defs.rs b/src/lang/inspect/defs.rs index c72227e5..101331b9 100644 --- a/src/lang/inspect/defs.rs +++ b/src/lang/inspect/defs.rs @@ -137,18 +137,31 @@ impl SymbolDef { /// Gets the name of the symbol. pub fn name(&self, db: &AnalysisDatabase) -> SmolStr { match self { - SymbolDef::Item(it) => it.name(db), - SymbolDef::Variable(it) => it.name(), - SymbolDef::ExprInlineMacro(name) => name.clone(), - SymbolDef::Member(it) => it.name(db), - SymbolDef::Module(it) => it.name(db), + Self::Item(it) => it.name(db), + Self::Variable(it) => it.name(), + Self::ExprInlineMacro(name) => name.clone(), + Self::Member(it) => it.name(db), + Self::Module(it) => it.name(db), } } /// Builds a search scope for finding usages of this symbol. + #[tracing::instrument(skip_all)] pub fn search_scope(&self, db: &AnalysisDatabase) -> SearchScope { - // TODO(mkaput): Narrow down the scope as much as possible for particular symbol kinds. - SearchScope::everything(db) + match &self { + Self::Variable(var) => { + match db.first_ancestor_of_kind(var.syntax_node(db), SyntaxKind::FunctionWithBody) { + Some(owning_function) => SearchScope::file_span( + owning_function.stable_ptr().file_id(db.upcast()), + owning_function.span(db.upcast()), + ), + None => SearchScope::file(var.definition_stable_ptr.file_id(db.upcast())), + } + } + + // TODO(#195): Use visibility information to narrow down search scopes. + _ => SearchScope::everything(db), + } } /// Starts a find-usages search for this symbol. @@ -332,6 +345,11 @@ impl VariableDef { Some(Self { name, var, definition_stable_ptr: param.stable_ptr().untyped() }) } + /// Gets the syntax node of the variable definition. + pub fn syntax_node(&self, db: &AnalysisDatabase) -> SyntaxNode { + self.definition_stable_ptr.lookup(db.upcast()) + } + /// Gets variable signature, which tries to resemble the way how it is defined in code. pub fn signature(&self, db: &AnalysisDatabase) -> String { let Self { name, var, .. } = self; diff --git a/src/lang/inspect/usages/search_scope.rs b/src/lang/inspect/usages/search_scope.rs index d22a42db..09c2a98d 100644 --- a/src/lang/inspect/usages/search_scope.rs +++ b/src/lang/inspect/usages/search_scope.rs @@ -35,6 +35,16 @@ impl SearchScope { this } + /// Builds a search scope spanning an entire single file. + pub fn file(file: FileId) -> Self { + Self { entries: [(file, None)].into() } + } + + /// Builds a search scope spanning a slice of a single file. + pub fn file_span(file: FileId, span: TextSpan) -> Self { + Self { entries: [(file, Some(span))].into() } + } + /// Creates an iterator over all files and the optional search scope text spans. pub fn files_and_spans(&self) -> impl Iterator)> + use<'_> { self.entries.iter().map(|(&file, &span)| (file, span))