@@ -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+
2228pub ( crate ) fn call_hierarchy (
2329 db : & RootDatabase ,
2430 position : FilePosition ,
@@ -28,6 +34,7 @@ pub(crate) fn call_hierarchy(
2834
2935pub ( 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
7690pub ( 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
189216fn 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
205233fn 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
221250fn 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
238268fn 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
260291fn 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
288320mod 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
309342fn 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
326360mod 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
347382fn caller1() {
@@ -365,6 +400,7 @@ fn caller3() {
365400 #[ test]
366401 fn test_call_hierarchy_issue_5103 ( ) {
367402 check_hierarchy (
403+ false ,
368404 r#"
369405fn a() {
370406 b()
@@ -382,6 +418,7 @@ fn main() {
382418 ) ;
383419
384420 check_hierarchy (
421+ false ,
385422 r#"
386423fn 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#"
406444macro_rules! define {
407445 ($ident:ident) => {
@@ -423,6 +461,7 @@ fn caller() {
423461 expect ! [ [ ] ] ,
424462 ) ;
425463 check_hierarchy (
464+ false ,
426465 r#"
427466macro_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#"
452492macro_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#"
620666trait 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}
0 commit comments