1+ //! This module implements a methods and free functions search in the specified file.
2+ //! We have to skip tests, so cannot reuse file_structure module.
3+
14use hir:: Semantics ;
25use ide_db:: RootDatabase ;
36use syntax:: { ast, ast:: NameOwner , AstNode , SyntaxNode } ;
@@ -10,12 +13,83 @@ pub(crate) fn find_all_methods(db: &RootDatabase, file_id: FileId) -> Vec<FileRa
1013 source_file. syntax ( ) . descendants ( ) . filter_map ( |it| method_range ( it, file_id) ) . collect ( )
1114}
1215
13- pub ( crate ) fn method_range ( item : SyntaxNode , file_id : FileId ) -> Option < FileRange > {
14- ast:: Fn :: cast ( item) . and_then ( |fn_def|{
16+ fn method_range ( item : SyntaxNode , file_id : FileId ) -> Option < FileRange > {
17+ ast:: Fn :: cast ( item) . and_then ( |fn_def| {
1518 if has_test_related_attribute ( & fn_def) {
1619 None
1720 } else {
18- fn_def. name ( ) . map ( |name| FileRange { file_id, range : name. syntax ( ) . text_range ( ) } )
21+ fn_def. name ( ) . map ( |name| FileRange { file_id, range : name. syntax ( ) . text_range ( ) } )
1922 }
2023 } )
2124}
25+
26+ #[ cfg( test) ]
27+ mod tests {
28+ use crate :: mock_analysis:: analysis_and_position;
29+ use crate :: { FileRange , TextSize } ;
30+ use std:: ops:: RangeInclusive ;
31+
32+ #[ test]
33+ fn test_find_all_methods ( ) {
34+ let ( analysis, pos) = analysis_and_position (
35+ r#"
36+ //- /lib.rs
37+ fn private_fn() {<|>}
38+
39+ pub fn pub_fn() {}
40+
41+ pub fn generic_fn<T>(arg: T) {}
42+ "# ,
43+ ) ;
44+
45+ let refs = analysis. find_all_methods ( pos. file_id ) . unwrap ( ) ;
46+ check_result ( & refs, & [ 3 ..=13 , 27 ..=33 , 47 ..=57 ] ) ;
47+ }
48+
49+ #[ test]
50+ fn test_find_trait_methods ( ) {
51+ let ( analysis, pos) = analysis_and_position (
52+ r#"
53+ //- /lib.rs
54+ trait Foo {
55+ fn bar() {<|>}
56+ fn baz() {}
57+ }
58+ "# ,
59+ ) ;
60+
61+ let refs = analysis. find_all_methods ( pos. file_id ) . unwrap ( ) ;
62+ check_result ( & refs, & [ 19 ..=22 , 35 ..=38 ] ) ;
63+ }
64+
65+ #[ test]
66+ fn test_skip_tests ( ) {
67+ let ( analysis, pos) = analysis_and_position (
68+ r#"
69+ //- /lib.rs
70+ #[test]
71+ fn foo() {<|>}
72+
73+ pub fn pub_fn() {}
74+
75+ mod tests {
76+ #[test]
77+ fn bar() {}
78+ }
79+ "# ,
80+ ) ;
81+
82+ let refs = analysis. find_all_methods ( pos. file_id ) . unwrap ( ) ;
83+ check_result ( & refs, & [ 28 ..=34 ] ) ;
84+ }
85+
86+ fn check_result ( refs : & [ FileRange ] , expected : & [ RangeInclusive < u32 > ] ) {
87+ assert_eq ! ( refs. len( ) , expected. len( ) ) ;
88+
89+ for ( i, item) in refs. iter ( ) . enumerate ( ) {
90+ let range = & expected[ i] ;
91+ assert_eq ! ( TextSize :: from( * range. start( ) ) , item. range. start( ) ) ;
92+ assert_eq ! ( TextSize :: from( * range. end( ) ) , item. range. end( ) ) ;
93+ }
94+ }
95+ }
0 commit comments