From 8579a9b834555339e400f3161280305a99189a5f Mon Sep 17 00:00:00 2001 From: Alexander Andreev Date: Sat, 6 Jul 2019 21:54:21 +0300 Subject: Added support attribute path in resolusion module fn --- crates/ra_hir/src/nameres/collector.rs | 29 +++++++++-- crates/ra_hir/src/nameres/tests.rs | 95 ++++++++++++++++++++++++++++++++++ 2 files changed, 119 insertions(+), 5 deletions(-) (limited to 'crates/ra_hir/src/nameres') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 951468a98..9f197bb58 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -1,6 +1,6 @@ use arrayvec::ArrayVec; use ra_db::FileId; -use ra_syntax::ast; +use ra_syntax::{ast, SmolStr}; use relative_path::RelativePathBuf; use rustc_hash::FxHashMap; use test_utils::tested_by; @@ -509,10 +509,16 @@ where .collect(&*items); } // out of line module, resolve, parse and recurse - raw::ModuleData::Declaration { name, ast_id, .. } => { + raw::ModuleData::Declaration { name, ast_id, attr_path } => { let ast_id = ast_id.with_file_id(self.file_id); let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); - match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { + match resolve_submodule( + self.def_collector.db, + self.file_id, + name, + is_root, + attr_path.as_ref(), + ) { Ok(file_id) => { let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); let raw_items = self.def_collector.db.raw_items(file_id.into()); @@ -626,6 +632,7 @@ fn resolve_submodule( file_id: HirFileId, name: &Name, is_root: bool, + attr_path: Option<&SmolStr>, ) -> Result { // FIXME: handle submodules of inline modules properly let file_id = file_id.original_file(db); @@ -639,7 +646,13 @@ fn resolve_submodule( let file_mod = dir_path.join(format!("{}.rs", name)); let dir_mod = dir_path.join(format!("{}/mod.rs", name)); let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name)); - let mut candidates = ArrayVec::<[_; 2]>::new(); + let mut candidates = ArrayVec::<[_; 3]>::new(); + let file_attr_mod = attr_path.map(|file_path| { + let file_attr_mod = dir_path.join(file_path.to_string()); + candidates.push(file_attr_mod.clone()); + + file_attr_mod + }); if is_dir_owner { candidates.push(file_mod.clone()); candidates.push(dir_mod); @@ -651,7 +664,13 @@ fn resolve_submodule( // FIXME: handle ambiguity match points_to.next() { Some(file_id) => Ok(file_id), - None => Err(if is_dir_owner { file_mod } else { file_dir_mod }), + None => { + if let Some(file_attr_mod) = file_attr_mod { + Err(file_attr_mod) + } else { + Err(if is_dir_owner { file_mod } else { file_dir_mod }) + } + } } } diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index bd2d855cf..5e8ea6780 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs @@ -364,6 +364,101 @@ fn module_resolution_works_for_raw_modules() { "###); } +#[test] +fn module_resolution_decl_path() { + let map = def_map_with_crate_graph( + " + //- /library.rs + #[path = \"bar/baz/foo.rs\"] + mod foo; + use self::foo::Bar; + + //- /bar/baz/foo.rs + pub struct Bar; + ", + crate_graph! { + "library": ("/library.rs", []), + }, + ); + + assert_snapshot_matches!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Bar: t v + "###); +} + +#[test] +fn module_resolution_module_with_path_in_mod_rs() { + let map = def_map_with_crate_graph( + " + //- /main.rs + mod foo; + + //- /foo/mod.rs + #[path = \"baz.rs\"] + pub mod bar; + + use self::bar::Baz; + + //- /foo/baz.rs + pub struct Baz; + ", + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot_matches!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Baz: t v + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +fn module_resolution_module_with_path_non_crate_root() { + let map = def_map_with_crate_graph( + " + //- /main.rs + mod foo; + + //- /foo.rs + #[path = \"baz.rs\"] + pub mod bar; + + use self::bar::Baz; + + //- /baz.rs + pub struct Baz; + ", + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot_matches!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Baz: t v + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + #[test] fn name_res_works_for_broken_modules() { covers!(name_res_works_for_broken_modules); -- cgit v1.2.3