@@ -19,6 +19,12 @@ pub struct CallItem {
1919pub 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 (
2329db : & RootDatabase ,
2430position : FilePosition ,
@@ -28,6 +34,7 @@ pub(crate) fn call_hierarchy(
2834
2935pub ( crate ) fn incoming_calls (
3036db : & RootDatabase ,
37+ CallHierarchyConfig { exclude_tests } : CallHierarchyConfig ,
3138FilePosition { file_id, offset } : FilePosition ,
3239) -> Option < Vec < CallItem > > {
3340let sema = & Semantics :: new ( db) ;
@@ -56,11 +63,18 @@ pub(crate) fn incoming_calls(
5663 references. iter ( ) . filter_map ( |FileReference { name, .. } | name. as_name_ref ( ) ) ;
5764for 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| {
6067let 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+
6478let range = sema. original_range ( name. syntax ( ) ) ;
6579 calls. add ( nav. call_site , range. into ( ) ) ;
6680if let Some ( other) = nav. def_site {
@@ -75,6 +89,7 @@ pub(crate) fn incoming_calls(
7589
7690pub ( crate ) fn outgoing_calls (
7791db : & RootDatabase ,
92+ CallHierarchyConfig { exclude_tests } : CallHierarchyConfig ,
7893FilePosition { file_id, offset } : FilePosition ,
7994) -> Option < Vec < CallItem > > {
8095let sema = Semantics :: new ( db) ;
@@ -103,7 +118,12 @@ pub(crate) fn outgoing_calls(
103118let expr = call. expr ( ) ?;
104119let callable = sema. type_of_expr ( & expr) ?. original . as_callable ( db) ?;
105120match 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) => {
114134let 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 {
149172use crate :: fixture;
150173
151174fn check_hierarchy (
175+ exclude_tests : bool ,
152176ra_fixture : & str ,
153177expected_nav : Expect ,
154178expected_incoming : Expect ,
@@ -172,18 +196,21 @@ mod tests {
172196let nav = navs. pop ( ) . unwrap ( ) ;
173197 expected_nav. assert_eq ( & nav. debug_render ( ) ) ;
174198
199+ let config = crate :: CallHierarchyConfig { exclude_tests } ;
200+
175201let item_pos =
176202FilePosition { 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]
185211fn test_call_hierarchy_on_ref ( ) {
186212check_hierarchy (
213+ false ,
187214r#"
188215//- /lib.rs
189216fn callee() {}
@@ -200,6 +227,7 @@ fn caller() {
200227#[ test]
201228fn test_call_hierarchy_on_def ( ) {
202229check_hierarchy (
230+ false ,
203231r#"
204232//- /lib.rs
205233fn call$0ee() {}
@@ -216,6 +244,7 @@ fn caller() {
216244#[ test]
217245fn test_call_hierarchy_in_same_fn ( ) {
218246check_hierarchy (
247+ false ,
219248r#"
220249//- /lib.rs
221250fn callee() {}
@@ -233,6 +262,7 @@ fn caller() {
233262#[ test]
234263fn test_call_hierarchy_in_different_fn ( ) {
235264check_hierarchy (
265+ false ,
236266r#"
237267//- /lib.rs
238268fn callee() {}
@@ -255,6 +285,7 @@ fn caller2() {
255285#[ test]
256286fn test_call_hierarchy_in_tests_mod ( ) {
257287check_hierarchy (
288+ false ,
258289r#"
259290//- /lib.rs cfg:test
260291fn callee() {}
@@ -283,6 +314,7 @@ mod tests {
283314#[ test]
284315fn test_call_hierarchy_in_different_files ( ) {
285316check_hierarchy (
317+ false ,
286318r#"
287319//- /lib.rs
288320mod foo;
@@ -304,6 +336,7 @@ pub fn callee() {}
304336#[ test]
305337fn test_call_hierarchy_outgoing ( ) {
306338check_hierarchy (
339+ false ,
307340r#"
308341//- /lib.rs
309342fn callee() {}
@@ -321,6 +354,7 @@ fn call$0er() {
321354#[ test]
322355fn test_call_hierarchy_outgoing_in_different_files ( ) {
323356check_hierarchy (
357+ false ,
324358r#"
325359//- /lib.rs
326360mod foo;
@@ -342,6 +376,7 @@ pub fn callee() {}
342376#[ test]
343377fn test_call_hierarchy_incoming_outgoing ( ) {
344378check_hierarchy (
379+ false ,
345380r#"
346381//- /lib.rs
347382fn caller1() {
@@ -365,6 +400,7 @@ fn caller3() {
365400#[ test]
366401fn test_call_hierarchy_issue_5103 ( ) {
367402check_hierarchy (
403+ false ,
368404r#"
369405fn a() {
370406 b()
@@ -382,6 +418,7 @@ fn main() {
382418) ;
383419
384420check_hierarchy (
421+ false ,
385422r#"
386423fn a() {
387424 b$0()
@@ -402,6 +439,7 @@ fn main() {
402439#[ test]
403440fn test_call_hierarchy_in_macros_incoming ( ) {
404441check_hierarchy (
442+ false ,
405443r#"
406444macro_rules! define {
407445 ($ident:ident) => {
@@ -423,6 +461,7 @@ fn caller() {
423461expect ! [ [ ] ] ,
424462) ;
425463check_hierarchy (
464+ false ,
426465r#"
427466macro_rules! define {
428467 ($ident:ident) => {
@@ -448,6 +487,7 @@ fn caller() {
448487#[ test]
449488fn test_call_hierarchy_in_macros_outgoing ( ) {
450489check_hierarchy (
490+ false ,
451491r#"
452492macro_rules! define {
453493 ($ident:ident) => {
@@ -473,6 +513,7 @@ fn caller$0() {
473513#[ test]
474514fn test_call_hierarchy_in_macros_incoming_different_files ( ) {
475515check_hierarchy (
516+ false ,
476517r#"
477518//- /lib.rs
478519#[macro_use]
@@ -498,6 +539,7 @@ macro_rules! call {
498539expect ! [ [ ] ] ,
499540) ;
500541check_hierarchy (
542+ false ,
501543r#"
502544//- /lib.rs
503545#[macro_use]
@@ -523,6 +565,7 @@ macro_rules! call {
523565expect ! [ [ ] ] ,
524566) ;
525567check_hierarchy (
568+ false ,
526569r#"
527570//- /lib.rs
528571#[macro_use]
@@ -558,6 +601,7 @@ macro_rules! call {
558601#[ test]
559602fn test_call_hierarchy_in_macros_outgoing_different_files ( ) {
560603check_hierarchy (
604+ false ,
561605r#"
562606//- /lib.rs
563607#[macro_use]
@@ -585,6 +629,7 @@ macro_rules! call {
585629expect ! [ [ ] ] ,
586630) ;
587631check_hierarchy (
632+ false ,
588633r#"
589634//- /lib.rs
590635#[macro_use]
@@ -616,6 +661,7 @@ macro_rules! call {
616661#[ test]
617662fn test_trait_method_call_hierarchy ( ) {
618663check_hierarchy (
664+ false ,
619665r#"
620666trait T1 {
621667 fn call$0ee();
@@ -636,4 +682,64 @@ fn caller() {
636682expect ! [ [ ] ] ,
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