aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_ide/src/parent_module.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2020-02-06 14:36:32 +0000
committerAleksey Kladov <[email protected]>2020-02-06 14:47:33 +0000
commit832dfae25024b8e6da097bfbf99a6b749e5e0ad0 (patch)
tree964172a911af7bb7e57c26b5e8e08467e9cb9c2e /crates/ra_ide/src/parent_module.rs
parentff2d77bde6acffc5e4c42878606b3d6d92300e11 (diff)
Tweak goto parent module
Diffstat (limited to 'crates/ra_ide/src/parent_module.rs')
-rw-r--r--crates/ra_ide/src/parent_module.rs37
1 files changed, 36 insertions, 1 deletions
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};
9use test_utils::tested_by;
9 10
10use crate::NavigationTarget; 11use crate::NavigationTarget;
11 12
@@ -14,7 +15,21 @@ use crate::NavigationTarget;
14pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec<NavigationTarget> { 15pub(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> {
41mod tests { 56mod 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 "