Skip to content

Commit e4146af

Browse files
committed
Auto merge of rust-lang#16441 - Young-Flash:exclude_tests_refs, r=Veykril
feat: enable excluding refs search results in test ## Change Here I introduce a new `ReferenceCategory::Test` type to indicate whether the function where this reference is located is marked as `#[test]`, and expose an config item (`rust-analyzer.references.excludeTests`) to client. I also changed the signature of `ReferenceCategory::new`, adding a `sema: &Semantics<'_, RootDatabase>` param to do some hir analysis. Hope the current implementation is good to go. ## Demo `"rust-analyzer.references.excludeTests": false` ![include](https://github.com/rust-lang/rust-analyzer/assets/71162630/9f1176d4-7b41-4f49-ac79-55d25a42d5d1) `"rust-analyzer.references.excludeTests": true` ![exclude](https://github.com/rust-lang/rust-analyzer/assets/71162630/2938b44b-9e5b-48de-a049-453f5bbc09d0) close rust-lang/rust-analyzer#14530
2 parents 9a832c4 + 2b71aca commit e4146af

File tree

8 files changed

+91
-8
lines changed

8 files changed

+91
-8
lines changed

crates/ide-db/src/search.rs

Lines changed: 22 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ pub enum ReferenceCategory {
134134
// FIXME: Some day should be able to search in doc comments. Would probably
135135
// need to switch from enum to bitflags then?
136136
// DocComment
137+
Test,
137138
}
138139

139140
/// Generally, `search_scope` returns files that might contain references for the element.
@@ -743,7 +744,7 @@ impl<'a> FindUsages<'a> {
743744
let reference = FileReference {
744745
range,
745746
name: FileReferenceNode::NameRef(name_ref.clone()),
746-
category: ReferenceCategory::new(&def, name_ref),
747+
category: ReferenceCategory::new(self.sema, &def, name_ref),
747748
};
748749
sink(file_id, reference)
749750
}
@@ -759,7 +760,7 @@ impl<'a> FindUsages<'a> {
759760
let reference = FileReference {
760761
range,
761762
name: FileReferenceNode::NameRef(name_ref.clone()),
762-
category: ReferenceCategory::new(&def, name_ref),
763+
category: ReferenceCategory::new(self.sema, &def, name_ref),
763764
};
764765
sink(file_id, reference)
765766
}
@@ -769,7 +770,7 @@ impl<'a> FindUsages<'a> {
769770
let reference = FileReference {
770771
range,
771772
name: FileReferenceNode::NameRef(name_ref.clone()),
772-
category: ReferenceCategory::new(&def, name_ref),
773+
category: ReferenceCategory::new(self.sema, &def, name_ref),
773774
};
774775
sink(file_id, reference)
775776
} else {
@@ -783,10 +784,10 @@ impl<'a> FindUsages<'a> {
783784
let local = Definition::Local(local);
784785
let access = match self.def {
785786
Definition::Field(_) if field == self.def => {
786-
ReferenceCategory::new(&field, name_ref)
787+
ReferenceCategory::new(self.sema, &field, name_ref)
787788
}
788789
Definition::Local(_) if local == self.def => {
789-
ReferenceCategory::new(&local, name_ref)
790+
ReferenceCategory::new(self.sema, &local, name_ref)
790791
}
791792
_ => return false,
792793
};
@@ -871,7 +872,15 @@ fn def_to_ty(sema: &Semantics<'_, RootDatabase>, def: &Definition) -> Option<hir
871872
}
872873

873874
impl ReferenceCategory {
874-
fn new(def: &Definition, r: &ast::NameRef) -> Option<ReferenceCategory> {
875+
fn new(
876+
sema: &Semantics<'_, RootDatabase>,
877+
def: &Definition,
878+
r: &ast::NameRef,
879+
) -> Option<ReferenceCategory> {
880+
if is_name_ref_in_test(sema, r) {
881+
return Some(ReferenceCategory::Test);
882+
}
883+
875884
// Only Locals and Fields have accesses for now.
876885
if !matches!(def, Definition::Local(_) | Definition::Field(_)) {
877886
return is_name_ref_in_import(r).then_some(ReferenceCategory::Import);
@@ -910,3 +919,10 @@ fn is_name_ref_in_import(name_ref: &ast::NameRef) -> bool {
910919
.and_then(|it| it.parent_path().top_path().syntax().parent())
911920
.map_or(false, |it| it.kind() == SyntaxKind::USE_TREE)
912921
}
922+
923+
fn is_name_ref_in_test(sema: &Semantics<'_, RootDatabase>, name_ref: &ast::NameRef) -> bool {
924+
name_ref.syntax().ancestors().any(|node| match ast::Fn::cast(node) {
925+
Some(it) => sema.to_def(&it).map_or(false, |func| func.is_test(sema.db)),
926+
None => false,
927+
})
928+
}

crates/ide/src/highlight_related.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,7 @@ mod tests {
519519
ReferenceCategory::Read => "read",
520520
ReferenceCategory::Write => "write",
521521
ReferenceCategory::Import => "import",
522+
ReferenceCategory::Test => "test",
522523
}
523524
.to_string()
524525
}),

crates/ide/src/references.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -307,6 +307,51 @@ mod tests {
307307

308308
use crate::{fixture, SearchScope};
309309

310+
#[test]
311+
fn exclude_tests() {
312+
check(
313+
r#"
314+
fn test_func() {}
315+
316+
fn func() {
317+
test_func$0();
318+
}
319+
320+
#[test]
321+
fn test() {
322+
test_func();
323+
}
324+
"#,
325+
expect![[r#"
326+
test_func Function FileId(0) 0..17 3..12
327+
328+
FileId(0) 35..44
329+
FileId(0) 75..84 Test
330+
"#]],
331+
);
332+
333+
check(
334+
r#"
335+
fn test_func() {}
336+
337+
fn func() {
338+
test_func$0();
339+
}
340+
341+
#[::core::prelude::v1::test]
342+
fn test() {
343+
test_func();
344+
}
345+
"#,
346+
expect![[r#"
347+
test_func Function FileId(0) 0..17 3..12
348+
349+
FileId(0) 35..44
350+
FileId(0) 96..105 Test
351+
"#]],
352+
);
353+
}
354+
310355
#[test]
311356
fn test_struct_literal_after_space() {
312357
check(
@@ -454,6 +499,7 @@ fn main() {
454499
"#]],
455500
);
456501
}
502+
457503
#[test]
458504
fn test_variant_tuple_before_paren() {
459505
check(
@@ -1435,7 +1481,7 @@ fn test$0() {
14351481
expect![[r#"
14361482
test Function FileId(0) 0..33 11..15
14371483
1438-
FileId(0) 24..28
1484+
FileId(0) 24..28 Test
14391485
"#]],
14401486
);
14411487
}

crates/rust-analyzer/src/config.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -494,6 +494,9 @@ config_data! {
494494
/// Exclude imports from find-all-references.
495495
references_excludeImports: bool = "false",
496496

497+
/// Exclude tests from find-all-references.
498+
references_excludeTests: bool = "false",
499+
497500
/// Allow renaming of items not belonging to the loaded workspaces.
498501
rename_allowExternalItems: bool = "false",
499502

@@ -1545,6 +1548,10 @@ impl Config {
15451548
self.data.references_excludeImports
15461549
}
15471550

1551+
pub fn find_all_refs_exclude_tests(&self) -> bool {
1552+
self.data.references_excludeTests
1553+
}
1554+
15481555
pub fn snippet_cap(&self) -> bool {
15491556
self.experimental("snippetTextEdit")
15501557
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,7 @@ pub(crate) fn handle_references(
10551055
let position = from_proto::file_position(&snap, params.text_document_position)?;
10561056

10571057
let exclude_imports = snap.config.find_all_refs_exclude_imports();
1058+
let exclude_tests = snap.config.find_all_refs_exclude_tests();
10581059

10591060
let refs = match snap.analysis.find_all_refs(position, None)? {
10601061
None => return Ok(None),
@@ -1078,7 +1079,8 @@ pub(crate) fn handle_references(
10781079
.flat_map(|(file_id, refs)| {
10791080
refs.into_iter()
10801081
.filter(|&(_, category)| {
1081-
!exclude_imports || category != Some(ReferenceCategory::Import)
1082+
(!exclude_imports || category != Some(ReferenceCategory::Import))
1083+
&& (!exclude_tests || category != Some(ReferenceCategory::Test))
10821084
})
10831085
.map(move |(range, _)| FileRange { file_id, range })
10841086
})

crates/rust-analyzer/src/lsp/to_proto.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@ pub(crate) fn document_highlight_kind(
9292
ReferenceCategory::Read => Some(lsp_types::DocumentHighlightKind::READ),
9393
ReferenceCategory::Write => Some(lsp_types::DocumentHighlightKind::WRITE),
9494
ReferenceCategory::Import => None,
95+
ReferenceCategory::Test => None,
9596
}
9697
}
9798

docs/user/generated_config.adoc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -777,6 +777,11 @@ Internal config, path to proc-macro server executable.
777777
--
778778
Exclude imports from find-all-references.
779779
--
780+
[[rust-analyzer.references.excludeTests]]rust-analyzer.references.excludeTests (default: `false`)::
781+
+
782+
--
783+
Exclude tests from find-all-references.
784+
--
780785
[[rust-analyzer.rename.allowExternalItems]]rust-analyzer.rename.allowExternalItems (default: `false`)::
781786
+
782787
--

editors/code/package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,6 +1505,11 @@
15051505
"default": false,
15061506
"type": "boolean"
15071507
},
1508+
"rust-analyzer.references.excludeTests": {
1509+
"markdownDescription": "Exclude tests from find-all-references.",
1510+
"default": false,
1511+
"type": "boolean"
1512+
},
15081513
"rust-analyzer.rename.allowExternalItems": {
15091514
"markdownDescription": "Allow renaming of items not belonging to the loaded workspaces.",
15101515
"default": false,

0 commit comments

Comments
 (0)