Resolve out of line modules inside inline module with attribute path
Fixed #1510 Fixed #1529
This commit is contained in:
parent
0ca30b6c4b
commit
83fe7b5fcb
@ -483,7 +483,7 @@ struct ModCollector<'a, D> {
|
||||
module_id: CrateModuleId,
|
||||
file_id: HirFileId,
|
||||
raw_items: &'a raw::RawItems,
|
||||
parent_module: Option<&'a Name>,
|
||||
parent_module: Option<ParentModule<'a>>,
|
||||
}
|
||||
|
||||
impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>>
|
||||
@ -508,15 +508,16 @@ where
|
||||
fn collect_module(&mut self, module: &raw::ModuleData) {
|
||||
match module {
|
||||
// inline module, just recurse
|
||||
raw::ModuleData::Definition { name, items, ast_id } => {
|
||||
raw::ModuleData::Definition { name, items, ast_id, attr_path } => {
|
||||
let module_id =
|
||||
self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
|
||||
let parent_module = ParentModule { name, attr_path: attr_path.as_ref() };
|
||||
ModCollector {
|
||||
def_collector: &mut *self.def_collector,
|
||||
module_id,
|
||||
file_id: self.file_id,
|
||||
raw_items: self.raw_items,
|
||||
parent_module: Some(name),
|
||||
parent_module: Some(parent_module),
|
||||
}
|
||||
.collect(&*items);
|
||||
}
|
||||
@ -530,7 +531,7 @@ where
|
||||
name,
|
||||
is_root,
|
||||
attr_path.as_ref(),
|
||||
self.parent_module,
|
||||
self.parent_module.as_ref(),
|
||||
) {
|
||||
Ok(file_id) => {
|
||||
let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
|
||||
@ -647,7 +648,7 @@ fn resolve_submodule(
|
||||
name: &Name,
|
||||
is_root: bool,
|
||||
attr_path: Option<&SmolStr>,
|
||||
parent_module: Option<&Name>,
|
||||
parent_module: Option<&ParentModule>,
|
||||
) -> Result<FileId, RelativePathBuf> {
|
||||
let file_id = file_id.original_file(db);
|
||||
let source_root_id = db.file_source_root(file_id);
|
||||
@ -657,20 +658,49 @@ fn resolve_submodule(
|
||||
let mod_name = path.file_stem().unwrap_or("unknown");
|
||||
|
||||
let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) {
|
||||
(Some(file_path), Some(parent_name)) => {
|
||||
(Some(file_path), Some(parent_module)) => {
|
||||
let file_path = normalize_attribute_path(file_path);
|
||||
let path = dir_path.join(format!("{}/{}", parent_name, file_path)).normalize();
|
||||
ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(path))
|
||||
match parent_module.attribute_path() {
|
||||
Some(parent_module_attr_path) => {
|
||||
let path = dir_path
|
||||
.join(format!(
|
||||
"{}/{}",
|
||||
normalize_attribute_path(parent_module_attr_path),
|
||||
file_path
|
||||
))
|
||||
.normalize();
|
||||
ResolutionMode::InlineModuleWithAttributePath(
|
||||
InsideInlineModuleMode::WithAttributePath(path),
|
||||
)
|
||||
}
|
||||
None => {
|
||||
let path =
|
||||
dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize();
|
||||
ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(
|
||||
path,
|
||||
))
|
||||
}
|
||||
}
|
||||
}
|
||||
(None, Some(parent_module)) => match parent_module.attribute_path() {
|
||||
Some(parent_module_attr_path) => {
|
||||
let path = dir_path.join(format!(
|
||||
"{}/{}.rs",
|
||||
normalize_attribute_path(parent_module_attr_path),
|
||||
name
|
||||
));
|
||||
ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path))
|
||||
}
|
||||
None => {
|
||||
let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name));
|
||||
ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path))
|
||||
}
|
||||
},
|
||||
(Some(file_path), None) => {
|
||||
let file_path = normalize_attribute_path(file_path);
|
||||
let path = dir_path.join(file_path.as_ref()).normalize();
|
||||
ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path))
|
||||
}
|
||||
(None, Some(parent_name)) => {
|
||||
let path = dir_path.join(format!("{}/{}.rs", parent_name, name));
|
||||
ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path))
|
||||
}
|
||||
_ => {
|
||||
let is_dir_owner = is_root || mod_name == "mod";
|
||||
if is_dir_owner {
|
||||
@ -743,6 +773,7 @@ impl InsideInlineModuleMode {
|
||||
enum ResolutionMode {
|
||||
OutOfLine(OutOfLineMode),
|
||||
InsideInlineModule(InsideInlineModuleMode),
|
||||
InlineModuleWithAttributePath(InsideInlineModuleMode),
|
||||
}
|
||||
|
||||
impl ResolutionMode {
|
||||
@ -752,6 +783,7 @@ impl ResolutionMode {
|
||||
match self {
|
||||
OutOfLine(mode) => mode.resolve(source_root),
|
||||
InsideInlineModule(mode) => mode.resolve(source_root),
|
||||
InlineModuleWithAttributePath(mode) => mode.resolve(source_root),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -773,6 +805,17 @@ fn resolve_find_result(
|
||||
}
|
||||
}
|
||||
|
||||
struct ParentModule<'a> {
|
||||
name: &'a Name,
|
||||
attr_path: Option<&'a SmolStr>,
|
||||
}
|
||||
|
||||
impl<'a> ParentModule<'a> {
|
||||
pub fn attribute_path(&self) -> Option<&SmolStr> {
|
||||
self.attr_path.filter(|p| !p.is_empty())
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use ra_db::SourceDatabase;
|
||||
|
@ -130,8 +130,17 @@ impl_arena_id!(Module);
|
||||
|
||||
#[derive(Debug, PartialEq, Eq)]
|
||||
pub(super) enum ModuleData {
|
||||
Declaration { name: Name, ast_id: FileAstId<ast::Module>, attr_path: Option<SmolStr> },
|
||||
Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> },
|
||||
Declaration {
|
||||
name: Name,
|
||||
ast_id: FileAstId<ast::Module>,
|
||||
attr_path: Option<SmolStr>,
|
||||
},
|
||||
Definition {
|
||||
name: Name,
|
||||
ast_id: FileAstId<ast::Module>,
|
||||
items: Vec<RawItem>,
|
||||
attr_path: Option<SmolStr>,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
|
||||
@ -256,9 +265,9 @@ impl RawItemsCollector {
|
||||
None => return,
|
||||
};
|
||||
|
||||
let attr_path = extract_mod_path_attribute(&module);
|
||||
let ast_id = self.source_ast_id_map.ast_id(&module);
|
||||
if module.has_semi() {
|
||||
let attr_path = extract_mod_path_attribute(&module);
|
||||
let item =
|
||||
self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id, attr_path });
|
||||
self.push_item(current_module, RawItem::Module(item));
|
||||
@ -266,10 +275,12 @@ impl RawItemsCollector {
|
||||
}
|
||||
|
||||
if let Some(item_list) = module.item_list() {
|
||||
let attr_path = extract_mod_path_attribute(&module);
|
||||
let item = self.raw_items.modules.alloc(ModuleData::Definition {
|
||||
name,
|
||||
ast_id,
|
||||
items: Vec::new(),
|
||||
attr_path,
|
||||
});
|
||||
self.process_module(Some(item), item_list);
|
||||
self.push_item(current_module, RawItem::Module(item));
|
||||
|
@ -336,9 +336,7 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() {
|
||||
"###);
|
||||
}
|
||||
|
||||
// FIXME: issue #1529. not support out-of-line modules inside inline.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn module_resolution_decl_inside_inline_module_with_path_attribute() {
|
||||
let map = def_map_with_crate_graph(
|
||||
r###"
|
||||
@ -397,9 +395,7 @@ fn module_resolution_decl_inside_inline_module() {
|
||||
"###);
|
||||
}
|
||||
|
||||
// FIXME: issue #1529. not support out-of-line modules inside inline.
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
|
||||
let map = def_map_with_crate_graph(
|
||||
r###"
|
||||
@ -429,9 +425,7 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() {
|
||||
"###);
|
||||
}
|
||||
|
||||
// FIXME: issue #1529. 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###"
|
||||
@ -462,9 +456,7 @@ fn module_resolution_decl_inside_inline_module_3() {
|
||||
"###);
|
||||
}
|
||||
|
||||
// FIXME: issue #1529. 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###"
|
||||
@ -475,7 +467,7 @@ fn module_resolution_decl_inside_inline_module_empty_path() {
|
||||
mod bar;
|
||||
}
|
||||
|
||||
//- /users.rs
|
||||
//- /foo/users.rs
|
||||
pub struct Baz;
|
||||
"###,
|
||||
crate_graph! {
|
||||
@ -520,9 +512,7 @@ fn module_resolution_decl_empty_path() {
|
||||
"###);
|
||||
}
|
||||
|
||||
// FIXME: issue #1529. 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###"
|
||||
@ -660,9 +650,7 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() {
|
||||
"###);
|
||||
}
|
||||
|
||||
// FIXME: issue #1529. 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###"
|
||||
|
Loading…
x
Reference in New Issue
Block a user