From 832dfae25024b8e6da097bfbf99a6b749e5e0ad0 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 6 Feb 2020 15:36:32 +0100 Subject: Tweak goto parent module --- crates/ra_ide/src/marks.rs | 1 + crates/ra_ide/src/parent_module.rs | 37 ++++++++++++++++++++++++++++++++++++- 2 files changed, 37 insertions(+), 1 deletion(-) 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!( call_info_bad_offset dont_complete_current_use dont_complete_primitive_in_use + test_resolve_parent_module_on_module_decl ); 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::{ algo::find_node_at_offset, ast::{self, AstNode}, }; +use test_utils::tested_by; use crate::NavigationTarget; @@ -14,7 +15,21 @@ use crate::NavigationTarget; pub(crate) fn parent_module(db: &RootDatabase, position: FilePosition) -> Vec { let mut sb = hir::SourceBinder::new(db); let parse = db.parse(position.file_id); - let module = match find_node_at_offset::(parse.tree().syntax(), position.offset) { + + let mut module = find_node_at_offset::(parse.tree().syntax(), position.offset); + + // If cursor is literally on `mod foo`, go to the grandpa. + if let Some(m) = &module { + if !m + .item_list() + .map_or(false, |it| it.syntax().text_range().contains_inclusive(position.offset)) + { + tested_by!(test_resolve_parent_module_on_module_decl); + module = m.syntax().ancestors().skip(1).find_map(ast::Module::cast); + } + } + + let module = match module { Some(module) => sb.to_def(hir::InFile::new(position.file_id.into(), module)), None => sb.to_module_def(position.file_id), }; @@ -41,6 +56,7 @@ pub(crate) fn crate_for(db: &RootDatabase, file_id: FileId) -> Vec { mod tests { use ra_cfg::CfgOptions; use ra_db::Env; + use test_utils::covers; use crate::{ mock_analysis::{analysis_and_position, MockAnalysis}, @@ -62,6 +78,25 @@ mod tests { nav.assert_match("foo MODULE FileId(1) [0; 8)"); } + #[test] + fn test_resolve_parent_module_on_module_decl() { + covers!(test_resolve_parent_module_on_module_decl); + let (analysis, pos) = analysis_and_position( + " + //- /lib.rs + mod foo; + + //- /foo.rs + mod <|>bar; + + //- /foo/bar.rs + // empty + ", + ); + let nav = analysis.parent_module(pos).unwrap().pop().unwrap(); + nav.assert_match("foo MODULE FileId(1) [0; 8)"); + } + #[test] fn test_resolve_parent_module_for_inline() { let (analysis, pos) = analysis_and_position( -- cgit v1.2.3