mirror of
https://github.com/rust-lang/rust-analyzer.git
synced 2025-10-01 11:31:15 +00:00
Merge #1528
1528: More resolution modules with attribute path r=matklad a=andreevlex #1211 Co-authored-by: Alexander Andreev <andreevlex.as@gmail.com>
This commit is contained in:
commit
c4e2e36e4c
@ -1,3 +1,5 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use arrayvec::ArrayVec;
|
||||
use ra_db::FileId;
|
||||
use ra_syntax::{ast, SmolStr};
|
||||
@ -84,7 +86,7 @@ struct DefCollector<DB> {
|
||||
global_macro_scope: FxHashMap<Name, MacroDefId>,
|
||||
|
||||
/// Some macro use `$tt:tt which mean we have to handle the macro perfectly
|
||||
/// To prevent stackoverflow, we add a deep counter here for prevent that.
|
||||
/// To prevent stack overflow, we add a deep counter here for prevent that.
|
||||
macro_stack_monitor: MacroStackMonitor,
|
||||
}
|
||||
|
||||
@ -649,7 +651,8 @@ fn resolve_submodule(
|
||||
let file_dir_mod = dir_path.join(format!("{}/{}.rs", mod_name, name));
|
||||
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());
|
||||
let file_path = normalize_attribute_path(file_path);
|
||||
let file_attr_mod = dir_path.join(file_path.as_ref()).normalize();
|
||||
candidates.push(file_attr_mod.clone());
|
||||
|
||||
file_attr_mod
|
||||
@ -675,6 +678,21 @@ fn resolve_submodule(
|
||||
}
|
||||
}
|
||||
|
||||
fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> {
|
||||
let current_dir = "./";
|
||||
let windows_path_separator = r#"\"#;
|
||||
let current_dir_normalize = if file_path.starts_with(current_dir) {
|
||||
&file_path[current_dir.len()..]
|
||||
} else {
|
||||
file_path.as_str()
|
||||
};
|
||||
if current_dir_normalize.contains(windows_path_separator) {
|
||||
Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/"))
|
||||
} else {
|
||||
Cow::Borrowed(current_dir_normalize)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ra_db::SourceDatabase;
|
||||
|
@ -80,15 +80,15 @@ fn module_resolution_works_for_raw_modules() {
|
||||
#[test]
|
||||
fn module_resolution_decl_path() {
|
||||
let map = def_map_with_crate_graph(
|
||||
"
|
||||
r###"
|
||||
//- /library.rs
|
||||
#[path = \"bar/baz/foo.rs\"]
|
||||
#[path = "bar/baz/foo.rs"]
|
||||
mod foo;
|
||||
use self::foo::Bar;
|
||||
|
||||
//- /bar/baz/foo.rs
|
||||
pub struct Bar;
|
||||
",
|
||||
"###,
|
||||
crate_graph! {
|
||||
"library": ("/library.rs", []),
|
||||
},
|
||||
@ -107,19 +107,19 @@ fn module_resolution_decl_path() {
|
||||
#[test]
|
||||
fn module_resolution_module_with_path_in_mod_rs() {
|
||||
let map = def_map_with_crate_graph(
|
||||
"
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
||||
//- /foo/mod.rs
|
||||
#[path = \"baz.rs\"]
|
||||
#[path = "baz.rs"]
|
||||
pub mod bar;
|
||||
|
||||
use self::bar::Baz;
|
||||
|
||||
//- /foo/baz.rs
|
||||
pub struct Baz;
|
||||
",
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
@ -141,19 +141,19 @@ fn module_resolution_module_with_path_in_mod_rs() {
|
||||
#[test]
|
||||
fn module_resolution_module_with_path_non_crate_root() {
|
||||
let map = def_map_with_crate_graph(
|
||||
"
|
||||
r###"
|
||||
//- /main.rs
|
||||
mod foo;
|
||||
|
||||
//- /foo.rs
|
||||
#[path = \"baz.rs\"]
|
||||
#[path = "baz.rs"]
|
||||
pub mod bar;
|
||||
|
||||
use self::bar::Baz;
|
||||
|
||||
//- /baz.rs
|
||||
pub struct Baz;
|
||||
",
|
||||
"###,
|
||||
crate_graph! {
|
||||
"main": ("/main.rs", []),
|
||||
},
|
||||
@ -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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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(
|
||||
r###"
|
||||
//- /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]
|
||||
fn unresolved_module_diagnostics() {
|
||||
let diagnostics = MockDatabase::with_files(
|
||||
|
Loading…
x
Reference in New Issue
Block a user