Skip to content

Commit 75ee986

Browse files
committed
feat: exclude refs from deps and stdlib
1 parent 9eb97ea commit 75ee986

7 files changed

Lines changed: 112 additions & 13 deletions

File tree

crates/ide-db/src/search.rs

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,8 @@ impl Definition {
449449
scope: None,
450450
include_self_kw_refs: None,
451451
search_self_mod: false,
452+
excluded_categories: ReferenceCategory::empty(),
453+
exclude_library_files: false,
452454
}
453455
}
454456
}
@@ -465,6 +467,10 @@ pub struct FindUsages<'a> {
465467
include_self_kw_refs: Option<hir::Type<'a>>,
466468
/// whether to search for the `self` module
467469
search_self_mod: bool,
470+
/// categories to exclude while collecting usages
471+
excluded_categories: ReferenceCategory,
472+
/// whether to skip files from library source roots
473+
exclude_library_files: bool,
468474
}
469475

470476
impl<'a> FindUsages<'a> {
@@ -495,6 +501,16 @@ impl<'a> FindUsages<'a> {
495501
self
496502
}
497503

504+
pub fn set_excluded_categories(mut self, categories: ReferenceCategory) -> Self {
505+
self.excluded_categories = categories;
506+
self
507+
}
508+
509+
pub fn set_exclude_library_files(mut self, exclude_library_files: bool) -> Self {
510+
self.exclude_library_files = exclude_library_files;
511+
self
512+
}
513+
498514
pub fn at_least_one(&self) -> bool {
499515
let mut found = false;
500516
self.search(&mut |_, _| {
@@ -599,7 +615,7 @@ impl<'a> FindUsages<'a> {
599615
search_scope: &SearchScope,
600616
name: &str,
601617
) -> bool {
602-
if self.scope.is_some() {
618+
if self.scope.is_some() || self.exclude_library_files {
603619
return false;
604620
}
605621

@@ -922,7 +938,7 @@ impl<'a> FindUsages<'a> {
922938
let _p = tracing::info_span!("FindUsages:search").entered();
923939
let sema = self.sema;
924940

925-
let search_scope = {
941+
let mut search_scope = {
926942
// FIXME: Is the trait scope needed for trait impl assoc items?
927943
let base =
928944
as_trait_assoc_def(sema.db, self.def).unwrap_or(self.def).search_scope(sema.db);
@@ -931,6 +947,14 @@ impl<'a> FindUsages<'a> {
931947
Some(scope) => base.intersection(scope),
932948
}
933949
};
950+
if self.exclude_library_files {
951+
search_scope
952+
.entries
953+
.retain(|&file_id, _| !is_library_file(sema.db, file_id.file_id(sema.db)));
954+
}
955+
if search_scope.entries.is_empty() {
956+
return;
957+
}
934958

935959
let name = match (self.rename, self.def) {
936960
(Some(rename), _) => {
@@ -1118,6 +1142,10 @@ impl<'a> FindUsages<'a> {
11181142
name_ref: &ast::NameRef,
11191143
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
11201144
) -> bool {
1145+
if self.is_excluded_name_ref(name_ref) {
1146+
return false;
1147+
}
1148+
11211149
// See https://github.com/rust-lang/rust-analyzer/pull/15864/files/e0276dc5ddc38c65240edb408522bb869f15afb4#r1389848845
11221150
let ty_eq = |ty: hir::Type<'_>| match (ty.as_adt(), self_ty.as_adt()) {
11231151
(Some(ty), Some(self_ty)) => ty == self_ty,
@@ -1146,6 +1174,10 @@ impl<'a> FindUsages<'a> {
11461174
name_ref: &ast::NameRef,
11471175
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
11481176
) -> bool {
1177+
if self.is_excluded_name_ref(name_ref) {
1178+
return false;
1179+
}
1180+
11491181
match NameRefClass::classify(self.sema, name_ref) {
11501182
Some(NameRefClass::Definition(def @ Definition::Module(_), _)) if def == self.def => {
11511183
let FileRange { file_id, range } = self.sema.original_range(name_ref.syntax());
@@ -1210,6 +1242,10 @@ impl<'a> FindUsages<'a> {
12101242
name_ref: &ast::NameRef,
12111243
sink: &mut dyn FnMut(EditionedFileId, FileReference) -> bool,
12121244
) -> bool {
1245+
if self.is_excluded_name_ref(name_ref) {
1246+
return false;
1247+
}
1248+
12131249
match NameRefClass::classify(self.sema, name_ref) {
12141250
Some(NameRefClass::Definition(def, _))
12151251
if self.def == def
@@ -1283,6 +1319,13 @@ impl<'a> FindUsages<'a> {
12831319
}
12841320
}
12851321

1322+
fn is_excluded_name_ref(&self, name_ref: &ast::NameRef) -> bool {
1323+
(self.excluded_categories.contains(ReferenceCategory::TEST)
1324+
&& is_name_ref_in_test(self.sema, name_ref))
1325+
|| (self.excluded_categories.contains(ReferenceCategory::IMPORT)
1326+
&& is_name_ref_in_import(name_ref))
1327+
}
1328+
12861329
fn found_name(
12871330
&self,
12881331
name: &ast::Name,
@@ -1409,3 +1452,8 @@ fn is_name_ref_in_test(sema: &Semantics<'_, RootDatabase>, name_ref: &ast::NameR
14091452
None => false,
14101453
})
14111454
}
1455+
1456+
fn is_library_file(db: &RootDatabase, file_id: span::FileId) -> bool {
1457+
let source_root = db.file_source_root(file_id).source_root_id(db);
1458+
db.source_root(source_root).source_root(db).is_library
1459+
}

crates/ide/src/annotations.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -216,7 +216,13 @@ pub(crate) fn resolve_annotation(
216216
*data = find_all_refs(
217217
&Semantics::new(db),
218218
pos,
219-
&FindAllRefsConfig { search_scope: None, ra_fixture: config.ra_fixture },
219+
&FindAllRefsConfig {
220+
search_scope: None,
221+
ra_fixture: config.ra_fixture,
222+
exclude_imports: false,
223+
exclude_tests: false,
224+
exclude_library_refs: false,
225+
},
220226
)
221227
.map(|result| {
222228
result

crates/ide/src/references.rs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ pub struct Declaration {
9191
pub struct FindAllRefsConfig<'a> {
9292
pub search_scope: Option<SearchScope>,
9393
pub ra_fixture: RaFixtureConfig<'a>,
94+
pub exclude_imports: bool,
95+
pub exclude_tests: bool,
96+
pub exclude_library_refs: bool,
9497
}
9598

9699
/// Find all references to the item at the given position.
@@ -127,8 +130,20 @@ pub(crate) fn find_all_refs(
127130
let syntax = sema.parse_guess_edition(position.file_id).syntax().clone();
128131
let make_searcher = |literal_search: bool| {
129132
move |def: Definition| {
130-
let mut usages =
131-
def.usages(sema).set_scope(config.search_scope.as_ref()).include_self_refs().all();
133+
let mut excluded_categories = ReferenceCategory::empty();
134+
if config.exclude_imports {
135+
excluded_categories |= ReferenceCategory::IMPORT;
136+
}
137+
if config.exclude_tests {
138+
excluded_categories |= ReferenceCategory::TEST;
139+
}
140+
let mut usages = def
141+
.usages(sema)
142+
.set_scope(config.search_scope.as_ref())
143+
.set_excluded_categories(excluded_categories)
144+
.set_exclude_library_files(config.exclude_library_refs)
145+
.include_self_refs()
146+
.all();
132147
if literal_search {
133148
retain_adt_literal_usages(&mut usages, def, sema);
134149
}
@@ -1568,6 +1583,9 @@ fn main() {
15681583
let config = FindAllRefsConfig {
15691584
search_scope: search_scope.map(|it| it(&analysis.db)),
15701585
ra_fixture: RaFixtureConfig::default(),
1586+
exclude_imports: false,
1587+
exclude_tests: false,
1588+
exclude_library_refs: false,
15711589
};
15721590
let refs = analysis.find_all_refs(pos, &config).unwrap().unwrap();
15731591

crates/rust-analyzer/src/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,9 @@ config_data! {
409409
/// Exclude imports from find-all-references.
410410
references_excludeImports: bool = false,
411411

412+
/// Exclude references from dependencies and stdlib in find-all-references.
413+
references_excludeLibraries: bool = false,
414+
412415
/// Exclude tests from find-all-references and call-hierarchy.
413416
references_excludeTests: bool = false,
414417

@@ -2652,6 +2655,10 @@ impl Config {
26522655
*self.references_excludeImports()
26532656
}
26542657

2658+
pub fn find_all_refs_exclude_libraries(&self) -> bool {
2659+
*self.references_excludeLibraries()
2660+
}
2661+
26552662
pub fn find_all_refs_exclude_tests(&self) -> bool {
26562663
*self.references_excludeTests()
26572664
}

crates/rust-analyzer/src/handlers/request.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ use base64::{Engine, prelude::BASE64_STANDARD};
99
use ide::{
1010
AssistKind, AssistResolveStrategy, Cancellable, CompletionFieldsToResolve, FilePosition,
1111
FileRange, FileStructureConfig, FindAllRefsConfig, HoverAction, HoverGotoTypeData,
12-
InlayFieldsToResolve, Query, RangeInfo, ReferenceCategory, Runnable, RunnableKind,
13-
SingleResolve, SourceChange, TextEdit,
12+
InlayFieldsToResolve, Query, RangeInfo, Runnable, RunnableKind, SingleResolve, SourceChange,
13+
TextEdit,
1414
};
1515
use ide_db::{FxHashMap, SymbolKind};
1616
use itertools::Itertools;
@@ -1396,12 +1396,16 @@ pub(crate) fn handle_references(
13961396

13971397
let exclude_imports = snap.config.find_all_refs_exclude_imports();
13981398
let exclude_tests = snap.config.find_all_refs_exclude_tests();
1399+
let exclude_library_refs = snap.config.find_all_refs_exclude_libraries();
13991400

14001401
let Some(refs) = snap.analysis.find_all_refs(
14011402
position,
14021403
&FindAllRefsConfig {
14031404
search_scope: None,
14041405
ra_fixture: snap.config.ra_fixture(snap.minicore()),
1406+
exclude_imports,
1407+
exclude_library_refs,
1408+
exclude_tests,
14051409
},
14061410
)?
14071411
else {
@@ -1423,12 +1427,7 @@ pub(crate) fn handle_references(
14231427
refs.references
14241428
.into_iter()
14251429
.flat_map(|(file_id, refs)| {
1426-
refs.into_iter()
1427-
.filter(|&(_, category)| {
1428-
(!exclude_imports || !category.contains(ReferenceCategory::IMPORT))
1429-
&& (!exclude_tests || !category.contains(ReferenceCategory::TEST))
1430-
})
1431-
.map(move |(range, _)| FileRange { file_id, range })
1430+
refs.into_iter().map(move |(range, _)| FileRange { file_id, range })
14321431
})
14331432
.chain(decl)
14341433
})
@@ -2211,7 +2210,11 @@ fn show_ref_command_link(
22112210
*position,
22122211
&FindAllRefsConfig {
22132212
search_scope: None,
2213+
22142214
ra_fixture: snap.config.ra_fixture(snap.minicore()),
2215+
exclude_imports: snap.config.find_all_refs_exclude_imports(),
2216+
exclude_tests: snap.config.find_all_refs_exclude_tests(),
2217+
exclude_library_refs: snap.config.find_all_refs_exclude_libraries(),
22152218
},
22162219
)
22172220
.unwrap_or(None)

docs/book/src/configuration_generated.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,6 +1376,13 @@ Default: `false`
13761376
Exclude imports from find-all-references.
13771377

13781378

1379+
## rust-analyzer.references.excludeLibraries {#references.excludeLibraries}
1380+
1381+
Default: `false`
1382+
1383+
Exclude references from dependencies and stdlib in find-all-references.
1384+
1385+
13791386
## rust-analyzer.references.excludeTests {#references.excludeTests}
13801387

13811388
Default: `false`

editors/code/package.json

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2875,6 +2875,16 @@
28752875
}
28762876
}
28772877
},
2878+
{
2879+
"title": "References",
2880+
"properties": {
2881+
"rust-analyzer.references.excludeLibraries": {
2882+
"markdownDescription": "Exclude references from dependencies and stdlib in find-all-references.",
2883+
"default": false,
2884+
"type": "boolean"
2885+
}
2886+
}
2887+
},
28782888
{
28792889
"title": "References",
28802890
"properties": {

0 commit comments

Comments
 (0)