From 83fe7b5fcb6c60b53f9ee3126b6b7995709840d3 Mon Sep 17 00:00:00 2001 From: Alexander Andreev Date: Sat, 3 Aug 2019 19:44:59 +0300 Subject: Resolve out of line modules inside inline module with attribute path Fixed #1510 Fixed #1529 --- crates/ra_hir/src/nameres/collector.rs | 67 ++++++++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 12 deletions(-) (limited to 'crates/ra_hir/src/nameres/collector.rs') diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 06b732215..7da2dcdff 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -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>, } impl 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 { 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; -- cgit v1.2.3