diff options
-rw-r--r-- | crates/ra_ide/src/marks.rs | 1 | ||||
-rw-r--r-- | crates/ra_ide/src/parent_module.rs | 37 |
2 files changed, 37 insertions, 1 deletions
diff --git a/crates/ra_ide/src/marks.rs b/crates/ra_ide/src/marks.rs index 077a44473..5bf4d2062 100644 --- a/crates/ra_ide/src/marks.rs +++ b/crates/ra_ide/src/marks.rs | |||
@@ -11,4 +11,5 @@ test_utils::marks!( | |||
11 | call_info_bad_offset | 11 | call_info_bad_offset |
12 | dont_complete_current_use | 12 | dont_complete_current_use |
13 | dont_complete_primitive_in_use | 13 | dont_complete_primitive_in_use |
14 | test_resolve_parent_module_on_module_decl | ||
14 | ); | 15 | ); |
diff --git a/crates/ra_ide/src/parent_module.rs b/crates/ra_ide/src/parent_module.rs index e0332da88..af14d6ab3 100644 --- a/crates/ra_ide/src/parent_module.rs +++ b/crates/ra_ide/src/parent_module.rs | |||
@@ -6,6 +6,7 @@ use ra_syntax::{ | |||
6 | algo::find_node_at_offset, | 6 | algo::find_node_at_offset, |
7 | ast::{self, AstNode}, | 7 | ast::{self, AstNode}, |
8 | }; | 8 | }; |
9 | use test_utils::tested_by; | ||
9 | 10 | ||
10 | use crate::NavigationTarget; | 11 | use crate::NavigationTarget; |
11 | 12 | ||
@@ -14,7 +15,21 @@ use crate::NavigationTarget; | |||
14 | pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<NavigationTarget> { | 15 | pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<NavigationTarget> { |
15 | let mut sb = hir::SourceBinder::new(db); | 16 | let mut sb = hir::SourceBinder::new(db); |
16 | let parse = db.parse(position.file_id); | 17 | let parse = db.parse(position.file_id); |
17 | let module = match find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset) { | 18 | |
19 | let mut module = find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset); | ||
20 | |||
21 | // If cursor is literally on `mod foo`, go to the grandpa. | ||
22 | if let Some(m) = &module { | ||
23 | if !m | ||
24 | .item_list() | ||
25 | .map_or(false, |it| it.syntax().text_range().contains_inclusive(position.offset)) | ||
26 | { | ||
27 | tested_by!(test_resolve_parent_module_on_module_decl); | ||
28 | module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast); | ||
29 | } | ||
30 | } | ||
31 | |||
32 | let module = match module { | ||
18 | Some(module) => sb.to_def(hir::InFile::new(position.file_id.into(), module)), | 33 | Some(module) => sb.to_def(hir::InFile::new(position.file_id.into(), module)), |
19 | None => sb.to_module_def(position.file_id), | 34 | None => sb.to_module_def(position.file_id), |
20 | }; | 35 | }; |
@@ -41,6 +56,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec<CrateId> { | |||
41 | mod tests { | 56 | mod tests { |
42 | use ra_cfg::CfgOptions; | 57 | use ra_cfg::CfgOptions; |
43 | use ra_db::Env; | 58 | use ra_db::Env; |
59 | use test_utils::covers; | ||
44 | 60 | ||
45 | use crate::{ | 61 | use crate::{ |
46 | mock_analysis::{analysis_and_position, MockAnalysis}, | 62 | mock_analysis::{analysis_and_position, MockAnalysis}, |
@@ -63,6 +79,25 @@ mod tests { | |||
63 | } | 79 | } |
64 | 80 | ||
65 | #[test] | 81 | #[test] |
82 | fn test_resolve_parent_module_on_module_decl() { | ||
83 | covers!(test_resolve_parent_module_on_module_decl); | ||
84 | let (analysis, pos) = analysis_and_position( | ||
85 | " | ||
86 | //- /lib.rs | ||
87 | mod foo; | ||
88 | |||
89 | //- /foo.rs | ||
90 | mod <|>bar; | ||
91 | |||
92 | //- /foo/bar.rs | ||
93 | // empty | ||
94 | ", | ||
95 | ); | ||
96 | let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); | ||
97 | nav.assert_match("foo MODULE FileId(1) [0; 8)"); | ||
98 | } | ||
99 | |||
100 | #[test] | ||
66 | fn test_resolve_parent_module_for_inline() { | 101 | fn test_resolve_parent_module_for_inline() { |
67 | let (analysis, pos) = analysis_and_position( | 102 | let (analysis, pos) = analysis_and_position( |
68 | " | 103 | " |