Unnamed repository; edit this file 'description' to name the repository.
-rw-r--r--crates/ide-db/src/search.rs52
-rw-r--r--crates/ide/src/annotations.rs8
-rw-r--r--crates/ide/src/references.rs22
-rw-r--r--crates/rust-analyzer/src/config.rs7
-rw-r--r--crates/rust-analyzer/src/handlers/request.rs19
-rw-r--r--docs/book/src/configuration_generated.md7
-rw-r--r--editors/code/package.json10
7 files changed, 112 insertions, 13 deletions
diff --git a/crates/ide-db/src/search.rs b/crates/ide-db/src/search.rs
index 69459a4b72..a0655341fa 100644
--- a/crates/ide-db/src/search.rs
+++ b/crates/ide-db/src/search.rs
@@ -449,6 +449,8 @@ impl Definition {
scope: None,
include_self_kw_refs: None,
search_self_mod: false,
+ excluded_categories: ReferenceCategory::empty(),
+ exclude_library_files: false,
}
}
}
@@ -465,6 +467,10 @@ pub struct FindUsages<'a> {
include_self_kw_refs: Option<hir::Type<'a>>,
/// whether to search for the `self` module
search_self_mod: bool,
+ /// categories to exclude while collecting usages
+ excluded_categories: ReferenceCategory,
+ /// whether to skip files from library source roots
+ exclude_library_files: bool,
}
impl<'a> FindUsages<'a> {
@@ -495,6 +501,16 @@ impl<'a> FindUsages<'a> {
self
}
+ pub fn set_excluded_categories(mut self, categories: ReferenceCategory) -> Self {
+ self.excluded_categories = categories;
+ self
+ }
+
+ pub fn set_exclude_library_files(mut self, exclude_library_files: bool) -> Self {
+ self.exclude_library_files = exclude_library_files;
+ self
+ }
+
pub fn at_least_one(&self) -> bool {
let mut found = false;
self.search(&mut |_, _| {
@@ -599,7 +615,7 @@ impl<'a> FindUsages<'a> {
search_scope: &SearchScope,
name: &str,
) -> bool {
- if self.scope.is_some() {
+ if self.scope.is_some() || self.exclude_library_files {
return false;
}
@@ -922,7 +938,7 @@ impl<'a> FindUsages<'a> {
let _p = tracing::info_span!("FindUsages:search").entered();
let sema = self.sema;
- let search_scope = {
+ let mut search_scope = {
// FIXME: Is the trait scope needed for trait impl assoc items?
let base =
as_trait_assoc_def(sema.db, self.def).unwrap_or(self.def).search_scope(sema.db);
@@ -931,6 +947,14 @@ impl<'a> FindUsages<'a> {
Some(scope) => base.intersection(scope),
}
};
+ if self.exclude_library_files {
+ search_scope
+ .entries
+ .retain(|&file_id, _| !is_library_file(sema.db, file_id.file_id(sema.db)));
+ }
+ if search_scope.entries.is_empty() {
+ return;
+ }
let name = match (self.rename, self.def) {
(Some(rename), _) => {
@@ -1118,6 +1142,10 @@ impl<'a> FindUsages<'a> {
name_ref: &ast::NameRef,
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
+ if self.is_excluded_name_ref(name_ref) {
+ return false;
+ }
+
// See https://github.com/rust-lang/rust-analyzer/pull/15864/files/e0276dc5ddc38c65240edb408522bb869f15afb4#r1389848845
let ty_eq = |ty: hir::Type<'_>| match (ty.as_adt(), self_ty.as_adt()) {
(Some(ty), Some(self_ty)) => ty == self_ty,
@@ -1146,6 +1174,10 @@ impl<'a> FindUsages<'a> {
name_ref: &ast::NameRef,
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
+ if self.is_excluded_name_ref(name_ref) {
+ return false;
+ }
+
match NameRefClass::classify(self.sema, name_ref) {
Some(NameRefClass::Definition(def @ Definition::Module(_), _)) if def == self.def => {
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
@@ -1210,6 +1242,10 @@ impl<'a> FindUsages<'a> {
name_ref: &ast::NameRef,
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
) -> bool {
+ if self.is_excluded_name_ref(name_ref) {
+ return false;
+ }
+
match NameRefClass::classify(self.sema, name_ref) {
Some(NameRefClass::Definition(def, _))
if self.def == def
@@ -1283,6 +1319,13 @@ impl<'a> FindUsages<'a> {
}
}
+ fn is_excluded_name_ref(&self, name_ref: &ast::NameRef) -> bool {
+ (self.excluded_categories.contains(ReferenceCategory::TEST)
+ && is_name_ref_in_test(self.sema, name_ref))
+ || (self.excluded_categories.contains(ReferenceCategory::IMPORT)
+ && is_name_ref_in_import(name_ref))
+ }
+
fn found_name(
&self,
name: &ast::Name,
@@ -1409,3 +1452,8 @@ fn is_name_ref_in_test(sema: &Semantics<'_, RootDatabase>, name_ref: &ast::NameR
None => false,
})
}
+
+fn is_library_file(db: &RootDatabase, file_id: span::FileId) -> bool {
+ let source_root = db.file_source_root(file_id).source_root_id(db);
+ db.source_root(source_root).source_root(db).is_library
+}
diff --git a/crates/ide/src/annotations.rs b/crates/ide/src/annotations.rs
index 21b2339c72..3d61b9d35f 100644
--- a/crates/ide/src/annotations.rs
+++ b/crates/ide/src/annotations.rs
@@ -216,7 +216,13 @@ pub(crate) fn resolve_annotation(
*data = find_all_refs(
&Semantics::new(db),
pos,
- &FindAllRefsConfig { search_scope: None, ra_fixture: config.ra_fixture },
+ &FindAllRefsConfig {
+ search_scope: None,
+ ra_fixture: config.ra_fixture,
+ exclude_imports: false,
+ exclude_tests: false,
+ exclude_library_refs: false,
+ },
)
.map(|result| {
result
diff --git a/crates/ide/src/references.rs b/crates/ide/src/references.rs
index 0288099bbc..c35e3dc3aa 100644
--- a/crates/ide/src/references.rs
+++ b/crates/ide/src/references.rs
@@ -91,6 +91,9 @@ pub struct Declaration {
pub struct FindAllRefsConfig<'a> {
pub search_scope: Option<SearchScope>,
pub ra_fixture: RaFixtureConfig<'a>,
+ pub exclude_imports: bool,
+ pub exclude_tests: bool,
+ pub exclude_library_refs: bool,
}
/// Find all references to the item at the given position.
@@ -127,8 +130,20 @@ pub(crate) fn find_all_refs(
let syntax = sema.parse_guess_edition(position.file_id).syntax().clone();
let make_searcher = |literal_search: bool| {
move |def: Definition| {
- let mut usages =
- def.usages(sema).set_scope(config.search_scope.as_ref()).include_self_refs().all();
+ let mut excluded_categories = ReferenceCategory::empty();
+ if config.exclude_imports {
+ excluded_categories |= ReferenceCategory::IMPORT;
+ }
+ if config.exclude_tests {
+ excluded_categories |= ReferenceCategory::TEST;
+ }
+ let mut usages = def
+ .usages(sema)
+ .set_scope(config.search_scope.as_ref())
+ .set_excluded_categories(excluded_categories)
+ .set_exclude_library_files(config.exclude_library_refs)
+ .include_self_refs()
+ .all();
if literal_search {
retain_adt_literal_usages(&mut usages, def, sema);
}
@@ -1568,6 +1583,9 @@ fn main() {
let config = FindAllRefsConfig {
search_scope: search_scope.map(|it| it(&analysis.db)),
ra_fixture: RaFixtureConfig::default(),
+ exclude_imports: false,
+ exclude_tests: false,
+ exclude_library_refs: false,
};
let refs = analysis.find_all_refs(pos, &config).unwrap().unwrap();
diff --git a/crates/rust-analyzer/src/config.rs b/crates/rust-analyzer/src/config.rs
index 3a88a8fe84..27546b50ca 100644
--- a/crates/rust-analyzer/src/config.rs
+++ b/crates/rust-analyzer/src/config.rs
@@ -409,6 +409,9 @@ config_data! {
/// Exclude imports from find-all-references.
references_excludeImports: bool = false,
+ /// Exclude references from dependencies and stdlib in find-all-references.
+ references_excludeLibraries: bool = false,
+
/// Exclude tests from find-all-references and call-hierarchy.
references_excludeTests: bool = false,
@@ -2652,6 +2655,10 @@ impl Config {
*self.references_excludeImports()
}
+ pub fn find_all_refs_exclude_libraries(&self) -> bool {
+ *self.references_excludeLibraries()
+ }
+
pub fn find_all_refs_exclude_tests(&self) -> bool {
*self.references_excludeTests()
}
diff --git a/crates/rust-analyzer/src/handlers/request.rs b/crates/rust-analyzer/src/handlers/request.rs
index 86516b6079..c6485badd4 100644
--- a/crates/rust-analyzer/src/handlers/request.rs
+++ b/crates/rust-analyzer/src/handlers/request.rs
@@ -9,8 +9,8 @@ use base64::{Engine, prelude::BASE64_STANDARD};
use ide::{
AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve, FilePosition,
FileRange, FileStructureConfig, FindAllRefsConfig, HoverAction, HoverGotoTypeData,
- InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
- SingleResolve, SourceChange, TextEdit,
+ InlayFieldsToResolve, Query, RangeInfo, Runnable, RunnableKind, SingleResolve, SourceChange,
+ TextEdit,
};
use ide_db::{FxHashMap, SymbolKind};
use itertools::Itertools;
@@ -1396,12 +1396,16 @@ pub(crate) fn handle_references(
let exclude_imports = snap.config.find_all_refs_exclude_imports();
let exclude_tests = snap.config.find_all_refs_exclude_tests();
+ let exclude_library_refs = snap.config.find_all_refs_exclude_libraries();
let Some(refs) = snap.analysis.find_all_refs(
position,
&FindAllRefsConfig {
search_scope: None,
ra_fixture: snap.config.ra_fixture(snap.minicore()),
+ exclude_imports,
+ exclude_library_refs,
+ exclude_tests,
},
)?
else {
@@ -1423,12 +1427,7 @@ pub(crate) fn handle_references(
refs.references
.into_iter()
.flat_map(|(file_id, refs)| {
- refs.into_iter()
- .filter(|&(_, category)| {
- (!exclude_imports || !category.contains(ReferenceCategory::IMPORT))
- && (!exclude_tests || !category.contains(ReferenceCategory::TEST))
- })
- .map(move |(range, _)| FileRange { file_id, range })
+ refs.into_iter().map(move |(range, _)| FileRange { file_id, range })
})
.chain(decl)
})
@@ -2211,7 +2210,11 @@ fn show_ref_command_link(
*position,
&FindAllRefsConfig {
search_scope: None,
+
ra_fixture: snap.config.ra_fixture(snap.minicore()),
+ exclude_imports: snap.config.find_all_refs_exclude_imports(),
+ exclude_tests: snap.config.find_all_refs_exclude_tests(),
+ exclude_library_refs: snap.config.find_all_refs_exclude_libraries(),
},
)
.unwrap_or(None)
diff --git a/docs/book/src/configuration_generated.md b/docs/book/src/configuration_generated.md
index da37fc1582..245e77f088 100644
--- a/docs/book/src/configuration_generated.md
+++ b/docs/book/src/configuration_generated.md
@@ -1376,6 +1376,13 @@ Default: `false`
Exclude imports from find-all-references.
+## rust-analyzer.references.excludeLibraries {#references.excludeLibraries}
+
+Default: `false`
+
+Exclude references from dependencies and stdlib in find-all-references.
+
+
## rust-analyzer.references.excludeTests {#references.excludeTests}
Default: `false`
diff --git a/editors/code/package.json b/editors/code/package.json
index 29cbc8bd4f..2f1d75816a 100644
--- a/editors/code/package.json
+++ b/editors/code/package.json
@@ -2878,6 +2878,16 @@
{
"title": "References",
"properties": {
+ "rust-analyzer.references.excludeLibraries": {
+ "markdownDescription": "Exclude references from dependencies and stdlib in find-all-references.",
+ "default": false,
+ "type": "boolean"
+ }
+ }
+ },
+ {
+ "title": "References",
+ "properties": {
"rust-analyzer.references.excludeTests": {
"markdownDescription": "Exclude tests from find-all-references and call-hierarchy.",
"default": false,