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>>
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);
}
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));
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);
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 {
enum ResolutionMode {
OutOfLine(OutOfLineMode),
InsideInlineModule(InsideInlineModuleMode),
+ InlineModuleWithAttributePath(InsideInlineModuleMode),
}
impl ResolutionMode {
match self {
OutOfLine(mode) => mode.resolve(source_root),
InsideInlineModule(mode) => mode.resolve(source_root),
+ InlineModuleWithAttributePath(mode) => mode.resolve(source_root),
}
}
}
}
}
+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;
#[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)]
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));
}
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));
"###);
}
-// 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###"
"###);
}
-// 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###"
"###);
}
-// 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###"
"###);
}
-// 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###"
mod bar;
}
- //- /users.rs
+ //- /foo/users.rs
pub struct Baz;
"###,
crate_graph! {
"###);
}
-// 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###"
"###);
}
-// 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###"