Skip to content

Commit d764d87

Browse files
committed
Auto merge of rust-lang#18291 - roife:fix-issue-18212, r=Veykril
feat: respect references.exclude_tests in call-hierarchy close rust-lang#18212 ### Changes 1. feat: respect `references.exclude_tests` in call-hierarchy 2. Modified the description of `references.exclude_tests`
2 parents b2048df + 7bc6150 commit d764d87

File tree

6 files changed

+141
-20
lines changed

6 files changed

+141
-20
lines changed

src/tools/rust-analyzer/crates/ide/src/call_hierarchy.rs

+112-6
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ pub struct CallItem {
1919
pub ranges: Vec<FileRange>,
2020
}
2121

22+
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
23+
pub struct CallHierarchyConfig {
24+
/// Whether to exclude tests from the call hierarchy
25+
pub exclude_tests: bool,
26+
}
27+
2228
pub(crate) fn call_hierarchy(
2329
db: &RootDatabase,
2430
position: FilePosition,
@@ -28,6 +34,7 @@ pub(crate) fn call_hierarchy(
2834

2935
pub(crate) fn incoming_calls(
3036
db: &RootDatabase,
37+
CallHierarchyConfig { exclude_tests }: CallHierarchyConfig,
3138
FilePosition { file_id, offset }: FilePosition,
3239
) -> Option<Vec<CallItem>> {
3340
let sema = &Semantics::new(db);
@@ -56,11 +63,18 @@ pub(crate) fn incoming_calls(
5663
references.iter().filter_map(|FileReference { name, .. }| name.as_name_ref());
5764
for name in references {
5865
// This target is the containing function
59-
let nav = sema.ancestors_with_macros(name.syntax().clone()).find_map(|node| {
66+
let def_nav = sema.ancestors_with_macros(name.syntax().clone()).find_map(|node| {
6067
let def = ast::Fn::cast(node).and_then(|fn_| sema.to_def(&fn_))?;
61-
def.try_to_nav(sema.db)
68+
// We should return def before check if it is a test, so that we
69+
// will not continue to search for outer fn in nested fns
70+
def.try_to_nav(sema.db).map(|nav| (def, nav))
6271
});
63-
if let Some(nav) = nav {
72+
73+
if let Some((def, nav)) = def_nav {
74+
if exclude_tests && def.is_test(db) {
75+
continue;
76+
}
77+
6478
let range = sema.original_range(name.syntax());
6579
calls.add(nav.call_site, range.into());
6680
if let Some(other) = nav.def_site {
@@ -75,6 +89,7 @@ pub(crate) fn incoming_calls(
7589

7690
pub(crate) fn outgoing_calls(
7791
db: &RootDatabase,
92+
CallHierarchyConfig { exclude_tests }: CallHierarchyConfig,
7893
FilePosition { file_id, offset }: FilePosition,
7994
) -> Option<Vec<CallItem>> {
8095
let sema = Semantics::new(db);
@@ -103,7 +118,12 @@ pub(crate) fn outgoing_calls(
103118
let expr = call.expr()?;
104119
let callable = sema.type_of_expr(&expr)?.original.as_callable(db)?;
105120
match callable.kind() {
106-
hir::CallableKind::Function(it) => it.try_to_nav(db),
121+
hir::CallableKind::Function(it) => {
122+
if exclude_tests && it.is_test(db) {
123+
return None;
124+
}
125+
it.try_to_nav(db)
126+
}
107127
hir::CallableKind::TupleEnumVariant(it) => it.try_to_nav(db),
108128
hir::CallableKind::TupleStruct(it) => it.try_to_nav(db),
109129
_ => None,
@@ -112,6 +132,9 @@ pub(crate) fn outgoing_calls(
112132
}
113133
ast::CallableExpr::MethodCall(expr) => {
114134
let function = sema.resolve_method_call(&expr)?;
135+
if exclude_tests && function.is_test(db) {
136+
return None;
137+
}
115138
function
116139
.try_to_nav(db)
117140
.zip(Some(sema.original_range(expr.name_ref()?.syntax())))
@@ -149,6 +172,7 @@ mod tests {
149172
use crate::fixture;
150173

151174
fn check_hierarchy(
175+
exclude_tests: bool,
152176
ra_fixture: &str,
153177
expected_nav: Expect,
154178
expected_incoming: Expect,
@@ -172,18 +196,21 @@ mod tests {
172196
let nav = navs.pop().unwrap();
173197
expected_nav.assert_eq(&nav.debug_render());
174198

199+
let config = crate::CallHierarchyConfig { exclude_tests };
200+
175201
let item_pos =
176202
FilePosition { file_id: nav.file_id, offset: nav.focus_or_full_range().start() };
177-
let incoming_calls = analysis.incoming_calls(item_pos).unwrap().unwrap();
203+
let incoming_calls = analysis.incoming_calls(config, item_pos).unwrap().unwrap();
178204
expected_incoming.assert_eq(&incoming_calls.into_iter().map(debug_render).join("\n"));
179205

180-
let outgoing_calls = analysis.outgoing_calls(item_pos).unwrap().unwrap();
206+
let outgoing_calls = analysis.outgoing_calls(config, item_pos).unwrap().unwrap();
181207
expected_outgoing.assert_eq(&outgoing_calls.into_iter().map(debug_render).join("\n"));
182208
}
183209

184210
#[test]
185211
fn test_call_hierarchy_on_ref() {
186212
check_hierarchy(
213+
false,
187214
r#"
188215
//- /lib.rs
189216
fn callee() {}
@@ -200,6 +227,7 @@ fn caller() {
200227
#[test]
201228
fn test_call_hierarchy_on_def() {
202229
check_hierarchy(
230+
false,
203231
r#"
204232
//- /lib.rs
205233
fn call$0ee() {}
@@ -216,6 +244,7 @@ fn caller() {
216244
#[test]
217245
fn test_call_hierarchy_in_same_fn() {
218246
check_hierarchy(
247+
false,
219248
r#"
220249
//- /lib.rs
221250
fn callee() {}
@@ -233,6 +262,7 @@ fn caller() {
233262
#[test]
234263
fn test_call_hierarchy_in_different_fn() {
235264
check_hierarchy(
265+
false,
236266
r#"
237267
//- /lib.rs
238268
fn callee() {}
@@ -255,6 +285,7 @@ fn caller2() {
255285
#[test]
256286
fn test_call_hierarchy_in_tests_mod() {
257287
check_hierarchy(
288+
false,
258289
r#"
259290
//- /lib.rs cfg:test
260291
fn callee() {}
@@ -283,6 +314,7 @@ mod tests {
283314
#[test]
284315
fn test_call_hierarchy_in_different_files() {
285316
check_hierarchy(
317+
false,
286318
r#"
287319
//- /lib.rs
288320
mod foo;
@@ -304,6 +336,7 @@ pub fn callee() {}
304336
#[test]
305337
fn test_call_hierarchy_outgoing() {
306338
check_hierarchy(
339+
false,
307340
r#"
308341
//- /lib.rs
309342
fn callee() {}
@@ -321,6 +354,7 @@ fn call$0er() {
321354
#[test]
322355
fn test_call_hierarchy_outgoing_in_different_files() {
323356
check_hierarchy(
357+
false,
324358
r#"
325359
//- /lib.rs
326360
mod foo;
@@ -342,6 +376,7 @@ pub fn callee() {}
342376
#[test]
343377
fn test_call_hierarchy_incoming_outgoing() {
344378
check_hierarchy(
379+
false,
345380
r#"
346381
//- /lib.rs
347382
fn caller1() {
@@ -365,6 +400,7 @@ fn caller3() {
365400
#[test]
366401
fn test_call_hierarchy_issue_5103() {
367402
check_hierarchy(
403+
false,
368404
r#"
369405
fn a() {
370406
b()
@@ -382,6 +418,7 @@ fn main() {
382418
);
383419

384420
check_hierarchy(
421+
false,
385422
r#"
386423
fn a() {
387424
b$0()
@@ -402,6 +439,7 @@ fn main() {
402439
#[test]
403440
fn test_call_hierarchy_in_macros_incoming() {
404441
check_hierarchy(
442+
false,
405443
r#"
406444
macro_rules! define {
407445
($ident:ident) => {
@@ -423,6 +461,7 @@ fn caller() {
423461
expect![[]],
424462
);
425463
check_hierarchy(
464+
false,
426465
r#"
427466
macro_rules! define {
428467
($ident:ident) => {
@@ -448,6 +487,7 @@ fn caller() {
448487
#[test]
449488
fn test_call_hierarchy_in_macros_outgoing() {
450489
check_hierarchy(
490+
false,
451491
r#"
452492
macro_rules! define {
453493
($ident:ident) => {
@@ -473,6 +513,7 @@ fn caller$0() {
473513
#[test]
474514
fn test_call_hierarchy_in_macros_incoming_different_files() {
475515
check_hierarchy(
516+
false,
476517
r#"
477518
//- /lib.rs
478519
#[macro_use]
@@ -498,6 +539,7 @@ macro_rules! call {
498539
expect![[]],
499540
);
500541
check_hierarchy(
542+
false,
501543
r#"
502544
//- /lib.rs
503545
#[macro_use]
@@ -523,6 +565,7 @@ macro_rules! call {
523565
expect![[]],
524566
);
525567
check_hierarchy(
568+
false,
526569
r#"
527570
//- /lib.rs
528571
#[macro_use]
@@ -558,6 +601,7 @@ macro_rules! call {
558601
#[test]
559602
fn test_call_hierarchy_in_macros_outgoing_different_files() {
560603
check_hierarchy(
604+
false,
561605
r#"
562606
//- /lib.rs
563607
#[macro_use]
@@ -585,6 +629,7 @@ macro_rules! call {
585629
expect![[]],
586630
);
587631
check_hierarchy(
632+
false,
588633
r#"
589634
//- /lib.rs
590635
#[macro_use]
@@ -616,6 +661,7 @@ macro_rules! call {
616661
#[test]
617662
fn test_trait_method_call_hierarchy() {
618663
check_hierarchy(
664+
false,
619665
r#"
620666
trait T1 {
621667
fn call$0ee();
@@ -636,4 +682,64 @@ fn caller() {
636682
expect![[]],
637683
);
638684
}
685+
686+
#[test]
687+
fn test_call_hierarchy_excluding_tests() {
688+
check_hierarchy(
689+
false,
690+
r#"
691+
fn main() {
692+
f1();
693+
}
694+
695+
fn f1$0() {
696+
f2(); f3();
697+
}
698+
699+
fn f2() {
700+
f1(); f3();
701+
}
702+
703+
#[test]
704+
fn f3() {
705+
f1(); f2();
706+
}
707+
"#,
708+
expect!["f1 Function FileId(0) 25..52 28..30"],
709+
expect![[r#"
710+
main Function FileId(0) 0..23 3..7 : FileId(0):16..18
711+
f2 Function FileId(0) 54..81 57..59 : FileId(0):68..70
712+
f3 Function FileId(0) 83..118 94..96 : FileId(0):105..107"#]],
713+
expect![[r#"
714+
f2 Function FileId(0) 54..81 57..59 : FileId(0):39..41
715+
f3 Function FileId(0) 83..118 94..96 : FileId(0):45..47"#]],
716+
);
717+
718+
check_hierarchy(
719+
true,
720+
r#"
721+
fn main() {
722+
f1();
723+
}
724+
725+
fn f1$0() {
726+
f2(); f3();
727+
}
728+
729+
fn f2() {
730+
f1(); f3();
731+
}
732+
733+
#[test]
734+
fn f3() {
735+
f1(); f2();
736+
}
737+
"#,
738+
expect!["f1 Function FileId(0) 25..52 28..30"],
739+
expect![[r#"
740+
main Function FileId(0) 0..23 3..7 : FileId(0):16..18
741+
f2 Function FileId(0) 54..81 57..59 : FileId(0):68..70"#]],
742+
expect!["f2 Function FileId(0) 54..81 57..59 : FileId(0):39..41"],
743+
);
744+
}
639745
}

src/tools/rust-analyzer/crates/ide/src/lib.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ use crate::navigation_target::ToNav;
7979

8080
pub use crate::{
8181
annotations::{Annotation, AnnotationConfig, AnnotationKind, AnnotationLocation},
82-
call_hierarchy::CallItem,
82+
call_hierarchy::{CallHierarchyConfig, CallItem},
8383
expand_macro::ExpandedMacro,
8484
file_structure::{StructureNode, StructureNodeKind},
8585
folding_ranges::{Fold, FoldKind},
@@ -564,13 +564,21 @@ impl Analysis {
564564
}
565565

566566
/// Computes incoming calls for the given file position.
567-
pub fn incoming_calls(&self, position: FilePosition) -> Cancellable<Option<Vec<CallItem>>> {
568-
self.with_db(|db| call_hierarchy::incoming_calls(db, position))
567+
pub fn incoming_calls(
568+
&self,
569+
config: CallHierarchyConfig,
570+
position: FilePosition,
571+
) -> Cancellable<Option<Vec<CallItem>>> {
572+
self.with_db(|db| call_hierarchy::incoming_calls(db, config, position))
569573
}
570574

571575
/// Computes outgoing calls for the given file position.
572-
pub fn outgoing_calls(&self, position: FilePosition) -> Cancellable<Option<Vec<CallItem>>> {
573-
self.with_db(|db| call_hierarchy::outgoing_calls(db, position))
576+
pub fn outgoing_calls(
577+
&self,
578+
config: CallHierarchyConfig,
579+
position: FilePosition,
580+
) -> Cancellable<Option<Vec<CallItem>>> {
581+
self.with_db(|db| call_hierarchy::outgoing_calls(db, config, position))
574582
}
575583

576584
/// Returns a `mod name;` declaration which created the current module.

src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs

+10-5
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,11 @@ use std::{
1212
use cfg::{CfgAtom, CfgDiff};
1313
use hir::Symbol;
1414
use ide::{
15-
AssistConfig, CallableSnippets, CompletionConfig, CompletionFieldsToResolve, DiagnosticsConfig,
16-
ExprFillDefaultMode, GenericParameterHints, HighlightConfig, HighlightRelatedConfig,
17-
HoverConfig, HoverDocFormat, InlayFieldsToResolve, InlayHintsConfig, JoinLinesConfig,
18-
MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind, Snippet, SnippetScope, SourceRootId,
15+
AssistConfig, CallHierarchyConfig, CallableSnippets, CompletionConfig,
16+
CompletionFieldsToResolve, DiagnosticsConfig, ExprFillDefaultMode, GenericParameterHints,
17+
HighlightConfig, HighlightRelatedConfig, HoverConfig, HoverDocFormat, InlayFieldsToResolve,
18+
InlayHintsConfig, JoinLinesConfig, MemoryLayoutHoverConfig, MemoryLayoutHoverRenderKind,
19+
Snippet, SnippetScope, SourceRootId,
1920
};
2021
use ide_db::{
2122
imports::insert_use::{ImportGranularity, InsertUseConfig, PrefixKind},
@@ -262,7 +263,7 @@ config_data! {
262263
/// Exclude imports from find-all-references.
263264
references_excludeImports: bool = false,
264265

265-
/// Exclude tests from find-all-references.
266+
/// Exclude tests from find-all-references and call-hierarchy.
266267
references_excludeTests: bool = false,
267268

268269
/// Inject additional highlighting into doc comments.
@@ -1392,6 +1393,10 @@ impl Config {
13921393
}
13931394
}
13941395

1396+
pub fn call_hierarchy(&self) -> CallHierarchyConfig {
1397+
CallHierarchyConfig { exclude_tests: self.references_excludeTests().to_owned() }
1398+
}
1399+
13951400
pub fn completion(&self, source_root: Option<SourceRootId>) -> CompletionConfig {
13961401
let client_capability_fields = self.completion_resolve_support_properties();
13971402
CompletionConfig {

0 commit comments

Comments
 (0)