mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-09-30 13:51:31 +00:00
parent
f1bfa8fc72
commit
1f0e9c149f
2 changed files with 521 additions and 4 deletions
|
@ -497,7 +497,7 @@ where
|
||||||
|
|
||||||
fn collect_module(&mut self, module: &raw::ModuleData) {
|
fn collect_module(&mut self, module: &raw::ModuleData) {
|
||||||
match module {
|
match module {
|
||||||
// inline module, just recurse
|
// inline module, just recursive
|
||||||
raw::ModuleData::Definition { name, items, ast_id } => {
|
raw::ModuleData::Definition { name, items, ast_id } => {
|
||||||
let module_id =
|
let module_id =
|
||||||
self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
|
self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
|
||||||
|
@ -509,7 +509,7 @@ where
|
||||||
}
|
}
|
||||||
.collect(&*items);
|
.collect(&*items);
|
||||||
}
|
}
|
||||||
// out of line module, resolve, parse and recurse
|
// out of line module, resolve, parse and recursive
|
||||||
raw::ModuleData::Declaration { name, ast_id, attr_path } => {
|
raw::ModuleData::Declaration { name, ast_id, attr_path } => {
|
||||||
let ast_id = ast_id.with_file_id(self.file_id);
|
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();
|
let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none();
|
||||||
|
@ -649,7 +649,8 @@ fn resolve_submodule(
|
||||||
let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
|
let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
|
||||||
let mut candidates = ArrayVec::<[_; 3]>::new();
|
let mut candidates = ArrayVec::<[_; 3]>::new();
|
||||||
let file_attr_mod = attr_path.map(|file_path| {
|
let file_attr_mod = attr_path.map(|file_path| {
|
||||||
let file_attr_mod = dir_path.join(file_path.to_string());
|
let file_path = normalize_attribute_path(file_path);
|
||||||
|
let file_attr_mod = dir_path.join(file_path).normalize();
|
||||||
candidates.push(file_attr_mod.clone());
|
candidates.push(file_attr_mod.clone());
|
||||||
|
|
||||||
file_attr_mod
|
file_attr_mod
|
||||||
|
@ -675,6 +676,17 @@ fn resolve_submodule(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn normalize_attribute_path(file_path: &SmolStr) -> String {
|
||||||
|
let current_dir = "./";
|
||||||
|
|
||||||
|
let separator = |path: &str| path.replace("\\", "/");
|
||||||
|
if file_path.starts_with(current_dir) {
|
||||||
|
separator(&file_path[current_dir.len()..])
|
||||||
|
} else {
|
||||||
|
separator(file_path.as_str())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use ra_db::SourceDatabase;
|
use ra_db::SourceDatabase;
|
||||||
|
|
|
@ -172,6 +172,511 @@ fn module_resolution_module_with_path_non_crate_root() {
|
||||||
"###);
|
"###);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_module_decl_path_super() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"bar/baz/module.rs\"]
|
||||||
|
mod foo;
|
||||||
|
pub struct Baz;
|
||||||
|
|
||||||
|
//- /bar/baz/module.rs
|
||||||
|
use super::Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮Baz: t v
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_explicit_path_mod_rs() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"module/mod.rs\"]
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /module/mod.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_relative_path() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
#[path = \"./sub.rs\"]
|
||||||
|
pub mod foo_bar;
|
||||||
|
|
||||||
|
//- /sub.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮foo_bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::foo_bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_relative_path_2() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
#[path=\"../sub.rs\"]
|
||||||
|
pub mod foo_bar;
|
||||||
|
|
||||||
|
//- /sub.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮foo_bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::foo_bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_explicit_path_mod_rs_2() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"module/bar/mod.rs\"]
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /module/bar/mod.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_explicit_path_mod_rs_with_win_separator() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"module\\bar\\mod.rs\"]
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /module/bar/mod.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"models\"]
|
||||||
|
mod foo {
|
||||||
|
mod bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /models/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_2() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"models/db\"]
|
||||||
|
mod foo {
|
||||||
|
mod bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /models/db/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_3() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"models/db\"]
|
||||||
|
mod foo {
|
||||||
|
#[path = \"users.rs\"]
|
||||||
|
mod bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /models/db/users.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_empty_path() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"\"]
|
||||||
|
mod foo {
|
||||||
|
#[path = \"users.rs\"]
|
||||||
|
mod bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /users.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn module_resolution_decl_empty_path() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"\"]
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_relative_path() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
#[path = \"./models\"]
|
||||||
|
mod foo {
|
||||||
|
mod bar;
|
||||||
|
}
|
||||||
|
|
||||||
|
//- /models/bar.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_in_crate_root() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo {
|
||||||
|
#[path = \"baz.rs\"]
|
||||||
|
mod bar;
|
||||||
|
}
|
||||||
|
use self::foo::bar::Baz;
|
||||||
|
|
||||||
|
//- /foo/baz.rs
|
||||||
|
pub struct Baz;
|
||||||
|
",
|
||||||
|
crate_graph! {
|
||||||
|
"main": ("/main.rs", []),
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert_snapshot_matches!(map, @r###"
|
||||||
|
⋮crate
|
||||||
|
⋮Baz: t v
|
||||||
|
⋮foo: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo
|
||||||
|
⋮bar: t
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_in_mod_rs() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo/mod.rs
|
||||||
|
mod bar {
|
||||||
|
#[path = \"qwe.rs\"]
|
||||||
|
pub mod baz;
|
||||||
|
}
|
||||||
|
use self::bar::baz::Baz;
|
||||||
|
|
||||||
|
//- /foo/bar/qwe.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
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar::baz
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
mod bar {
|
||||||
|
#[path = \"qwe.rs\"]
|
||||||
|
pub mod baz;
|
||||||
|
}
|
||||||
|
use self::bar::baz::Baz;
|
||||||
|
|
||||||
|
//- /foo/bar/qwe.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
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar::baz
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: issue #1510. not support out-of-line modules inside inline.
|
||||||
|
#[test]
|
||||||
|
#[ignore]
|
||||||
|
fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() {
|
||||||
|
let map = def_map_with_crate_graph(
|
||||||
|
"
|
||||||
|
//- /main.rs
|
||||||
|
mod foo;
|
||||||
|
|
||||||
|
//- /foo.rs
|
||||||
|
#[path = \"bar\"]
|
||||||
|
mod bar {
|
||||||
|
pub mod baz;
|
||||||
|
}
|
||||||
|
use self::bar::baz::Baz;
|
||||||
|
|
||||||
|
//- /bar/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
|
||||||
|
⋮
|
||||||
|
⋮crate::foo::bar::baz
|
||||||
|
⋮Baz: t v
|
||||||
|
"###);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn unresolved_module_diagnostics() {
|
fn unresolved_module_diagnostics() {
|
||||||
let diagnostics = MockDatabase::with_files(
|
let diagnostics = MockDatabase::with_files(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue