Added support attribute path in resolusion module fn

This commit is contained in:
Alexander Andreev 2019-07-06 21:54:21 +03:00
parent 35a0f04128
commit 8579a9b834
2 changed files with 119 additions and 5 deletions

View File

@ -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<FileId, RelativePathBuf> {
// 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 })
}
}
}
}

View File

@ -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);