From 3e5f7299e17c18358904240b08875bf82a9423f2 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Sep 2019 20:27:10 +0300 Subject: move mod resolution to a separate file --- crates/ra_hir/src/nameres.rs | 1 + crates/ra_hir/src/nameres/collector.rs | 190 +--------------------------- crates/ra_hir/src/nameres/mod_resolution.rs | 182 ++++++++++++++++++++++++++ 3 files changed, 190 insertions(+), 183 deletions(-) create mode 100644 crates/ra_hir/src/nameres/mod_resolution.rs diff --git a/crates/ra_hir/src/nameres.rs b/crates/ra_hir/src/nameres.rs index f69179bf6..dc2e2172b 100644 --- a/crates/ra_hir/src/nameres.rs +++ b/crates/ra_hir/src/nameres.rs @@ -50,6 +50,7 @@ mod per_ns; mod raw; mod collector; +mod mod_resolution; #[cfg(test)] mod tests; diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 5d1c42926..d6c7c083d 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs @@ -1,9 +1,5 @@ -use std::borrow::Cow; -use std::sync::Arc; - -use ra_db::{FileId, SourceRoot}; -use ra_syntax::{ast, SmolStr}; -use relative_path::RelativePathBuf; +use ra_db::FileId; +use ra_syntax::ast; use rustc_hash::FxHashMap; use test_utils::tested_by; @@ -12,8 +8,10 @@ use crate::{ ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, name::MACRO_RULES, nameres::{ - diagnostics::DefDiagnostic, raw, CrateDefMap, CrateModuleId, ItemOrMacro, ModuleData, - ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode, + diagnostics::DefDiagnostic, + mod_resolution::{resolve_submodule, ParentModule}, + raw, CrateDefMap, CrateModuleId, ItemOrMacro, ModuleData, ModuleDef, PerNs, + ReachedFixedPoint, Resolution, ResolveMode, }, AstId, Const, DefDatabase, Enum, Function, HirFileId, MacroDef, Module, Name, Path, Static, Struct, Trait, TypeAlias, Union, @@ -568,7 +566,7 @@ where name, is_root, attr_path.as_ref(), - self.parent_module.as_ref(), + self.parent_module, ) { Ok(file_id) => { let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); @@ -679,180 +677,6 @@ fn is_macro_rules(path: &Path) -> bool { path.as_ident() == Some(&MACRO_RULES) } -fn resolve_submodule( - db: &impl DefDatabase, - file_id: HirFileId, - name: &Name, - is_root: bool, - attr_path: Option<&SmolStr>, - parent_module: Option<&ParentModule>, -) -> Result { - let file_id = file_id.original_file(db); - let source_root_id = db.file_source_root(file_id); - let path = db.file_relative_path(file_id); - let root = RelativePathBuf::default(); - let dir_path = path.parent().unwrap_or(&root); - 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_module)) => { - let file_path = normalize_attribute_path(file_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)) - } - _ => { - let is_dir_owner = is_root || mod_name == "mod"; - if is_dir_owner { - let file_mod = dir_path.join(format!("{}.rs", name)); - let dir_mod = dir_path.join(format!("{}/mod.rs", name)); - ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs { - file: file_mod, - directory: dir_mod, - }) - } else { - let path = dir_path.join(format!("{}/{}.rs", mod_name, name)); - ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path)) - } - } - }; - - resolve_mode.resolve(db.source_root(source_root_id)) -} - -fn normalize_attribute_path(file_path: &SmolStr) -> Cow { - 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) - } -} - -enum OutOfLineMode { - RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf }, - FileInDirectory(RelativePathBuf), - WithAttributePath(RelativePathBuf), -} - -impl OutOfLineMode { - pub fn resolve(&self, source_root: Arc) -> Result { - match self { - OutOfLineMode::RootOrModRs { file, directory } => match source_root.files.get(file) { - None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()), - file_id => resolve_find_result(file_id, file), - }, - OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path), - OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path), - } - } -} - -enum InsideInlineModuleMode { - File(RelativePathBuf), - WithAttributePath(RelativePathBuf), -} - -impl InsideInlineModuleMode { - pub fn resolve(&self, source_root: Arc) -> Result { - match self { - InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path), - InsideInlineModuleMode::WithAttributePath(path) => { - resolve_simple_path(source_root, path) - } - } - } -} - -enum ResolutionMode { - OutOfLine(OutOfLineMode), - InsideInlineModule(InsideInlineModuleMode), - InlineModuleWithAttributePath(InsideInlineModuleMode), -} - -impl ResolutionMode { - pub fn resolve(&self, source_root: Arc) -> Result { - use self::ResolutionMode::*; - - match self { - OutOfLine(mode) => mode.resolve(source_root), - InsideInlineModule(mode) => mode.resolve(source_root), - InlineModuleWithAttributePath(mode) => mode.resolve(source_root), - } - } -} - -fn resolve_simple_path( - source_root: Arc, - path: &RelativePathBuf, -) -> Result { - resolve_find_result(source_root.files.get(path), path) -} - -fn resolve_find_result( - file_id: Option<&FileId>, - path: &RelativePathBuf, -) -> Result { - match file_id { - Some(file_id) => Ok(file_id.clone()), - None => Err(path.clone()), - } -} - -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; diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs new file mode 100644 index 000000000..94c9946ff --- /dev/null +++ b/crates/ra_hir/src/nameres/mod_resolution.rs @@ -0,0 +1,182 @@ +use std::{borrow::Cow, sync::Arc}; + +use ra_db::{FileId, SourceRoot}; +use ra_syntax::SmolStr; +use relative_path::RelativePathBuf; + +use crate::{DefDatabase, HirFileId, Name}; + +#[derive(Clone, Copy)] +pub(super) struct ParentModule<'a> { + pub(super) name: &'a Name, + pub(super) attr_path: Option<&'a SmolStr>, +} + +impl<'a> ParentModule<'a> { + fn attribute_path(&self) -> Option<&SmolStr> { + self.attr_path.filter(|p| !p.is_empty()) + } +} + +pub(super) fn resolve_submodule( + db: &impl DefDatabase, + file_id: HirFileId, + name: &Name, + is_root: bool, + attr_path: Option<&SmolStr>, + parent_module: Option>, +) -> Result { + let file_id = file_id.original_file(db); + let source_root_id = db.file_source_root(file_id); + let path = db.file_relative_path(file_id); + let root = RelativePathBuf::default(); + let dir_path = path.parent().unwrap_or(&root); + 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_module)) => { + let file_path = normalize_attribute_path(file_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)) + } + _ => { + let is_dir_owner = is_root || mod_name == "mod"; + if is_dir_owner { + let file_mod = dir_path.join(format!("{}.rs", name)); + let dir_mod = dir_path.join(format!("{}/mod.rs", name)); + ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs { + file: file_mod, + directory: dir_mod, + }) + } else { + let path = dir_path.join(format!("{}/{}.rs", mod_name, name)); + ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path)) + } + } + }; + + resolve_mode.resolve(db.source_root(source_root_id)) +} + +fn normalize_attribute_path(file_path: &SmolStr) -> Cow { + 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) + } +} + +enum OutOfLineMode { + RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf }, + FileInDirectory(RelativePathBuf), + WithAttributePath(RelativePathBuf), +} + +impl OutOfLineMode { + pub fn resolve(&self, source_root: Arc) -> Result { + match self { + OutOfLineMode::RootOrModRs { file, directory } => match source_root.files.get(file) { + None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()), + file_id => resolve_find_result(file_id, file), + }, + OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path), + OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path), + } + } +} + +enum InsideInlineModuleMode { + File(RelativePathBuf), + WithAttributePath(RelativePathBuf), +} + +impl InsideInlineModuleMode { + pub fn resolve(&self, source_root: Arc) -> Result { + match self { + InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path), + InsideInlineModuleMode::WithAttributePath(path) => { + resolve_simple_path(source_root, path) + } + } + } +} + +enum ResolutionMode { + OutOfLine(OutOfLineMode), + InsideInlineModule(InsideInlineModuleMode), + InlineModuleWithAttributePath(InsideInlineModuleMode), +} + +impl ResolutionMode { + pub fn resolve(&self, source_root: Arc) -> Result { + use self::ResolutionMode::*; + + match self { + OutOfLine(mode) => mode.resolve(source_root), + InsideInlineModule(mode) => mode.resolve(source_root), + InlineModuleWithAttributePath(mode) => mode.resolve(source_root), + } + } +} + +fn resolve_simple_path( + source_root: Arc, + path: &RelativePathBuf, +) -> Result { + resolve_find_result(source_root.files.get(path), path) +} + +fn resolve_find_result( + file_id: Option<&FileId>, + path: &RelativePathBuf, +) -> Result { + match file_id { + Some(file_id) => Ok(file_id.clone()), + None => Err(path.clone()), + } +} -- cgit v1.2.3 From 5a38a80d1ac2baa0579d7e58e5ab46355f5e2738 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 5 Sep 2019 21:43:32 +0300 Subject: rename test file to match impl file --- crates/ra_hir/src/nameres/tests.rs | 2 +- crates/ra_hir/src/nameres/tests/mod_resolution.rs | 708 ++++++++++++++++++++++ crates/ra_hir/src/nameres/tests/mods.rs | 708 ---------------------- 3 files changed, 709 insertions(+), 709 deletions(-) create mode 100644 crates/ra_hir/src/nameres/tests/mod_resolution.rs delete mode 100644 crates/ra_hir/src/nameres/tests/mods.rs diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index c1dbad283..4ff897ca5 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs @@ -2,7 +2,7 @@ mod macros; mod globs; mod incremental; mod primitives; -mod mods; +mod mod_resolution; use std::sync::Arc; diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir/src/nameres/tests/mod_resolution.rs new file mode 100644 index 000000000..4f8398460 --- /dev/null +++ b/crates/ra_hir/src/nameres/tests/mod_resolution.rs @@ -0,0 +1,708 @@ +use super::*; + +#[test] +fn name_res_works_for_broken_modules() { + covers!(name_res_works_for_broken_modules); + let map = def_map( + " + //- /lib.rs + mod foo // no `;`, no body + + use self::foo::Baz; + + //- /foo/mod.rs + pub mod bar; + + pub use self::bar::Baz; + + //- /foo/bar.rs + pub struct Baz; + ", + ); + assert_snapshot!(map, @r###" + ⋮crate + ⋮Baz: _ + "###); +} + +#[test] +fn module_resolution_works_for_non_standard_filenames() { + let map = def_map_with_crate_graph( + " + //- /my_library.rs + mod foo; + use self::foo::Bar; + + //- /foo/mod.rs + pub struct Bar; + ", + crate_graph! { + "my_library": ("/my_library.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Bar: t v + "###); +} + +#[test] +fn module_resolution_works_for_raw_modules() { + let map = def_map_with_crate_graph( + " + //- /library.rs + mod r#async; + use self::r#async::Bar; + + //- /async.rs + pub struct Bar; + ", + crate_graph! { + "library": ("/library.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮async: t + ⋮ + ⋮crate::async + ⋮Bar: t v + "###); +} + +#[test] +fn module_resolution_decl_path() { + let map = def_map_with_crate_graph( + r###" + //- /library.rs + #[path = "bar/baz/foo.rs"] + mod foo; + use self::foo::Bar; + + //- /bar/baz/foo.rs + pub struct Bar; + "###, + crate_graph! { + "library": ("/library.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮Bar: t v + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Bar: t v + "###); +} + +#[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"] + pub mod bar; + + use self::bar::Baz; + + //- /foo/baz.rs + pub struct Baz; + "###, + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Baz: t v + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[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"] + pub mod bar; + + use self::bar::Baz; + + //- /baz.rs + pub struct Baz; + "###, + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Baz: t v + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[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!(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!(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!(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!(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!(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!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Baz: t v + "###); +} + +#[test] +fn module_resolution_decl_inside_inline_module_with_path_attribute() { + 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!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +fn module_resolution_decl_inside_inline_module() { + let map = def_map_with_crate_graph( + r###" + //- /main.rs + mod foo { + mod bar; + } + + //- /foo/bar.rs + pub struct Baz; + "###, + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { + 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!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +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!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +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; + } + + //- /foo/users.rs + pub struct Baz; + "###, + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot!(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!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮Baz: t v + "###); +} + +#[test] +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!(map, @r###" + ⋮crate + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +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!(map, @r###" + ⋮crate + ⋮Baz: t v + ⋮foo: t + ⋮ + ⋮crate::foo + ⋮bar: t + ⋮ + ⋮crate::foo::bar + ⋮Baz: t v + "###); +} + +#[test] +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!(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 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; + + //- /bar/qwe.rs + pub struct Baz; + "###, + crate_graph! { + "main": ("/main.rs", []), + }, + ); + + assert_snapshot!(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 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!(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( + r" + //- /lib.rs + mod foo; + mod bar; + mod baz {} + //- /foo.rs + ", + ) + .diagnostics(); + + assert_snapshot!(diagnostics, @r###" + "mod bar;": unresolved module + "### + ); +} diff --git a/crates/ra_hir/src/nameres/tests/mods.rs b/crates/ra_hir/src/nameres/tests/mods.rs deleted file mode 100644 index 4f8398460..000000000 --- a/crates/ra_hir/src/nameres/tests/mods.rs +++ /dev/null @@ -1,708 +0,0 @@ -use super::*; - -#[test] -fn name_res_works_for_broken_modules() { - covers!(name_res_works_for_broken_modules); - let map = def_map( - " - //- /lib.rs - mod foo // no `;`, no body - - use self::foo::Baz; - - //- /foo/mod.rs - pub mod bar; - - pub use self::bar::Baz; - - //- /foo/bar.rs - pub struct Baz; - ", - ); - assert_snapshot!(map, @r###" - ⋮crate - ⋮Baz: _ - "###); -} - -#[test] -fn module_resolution_works_for_non_standard_filenames() { - let map = def_map_with_crate_graph( - " - //- /my_library.rs - mod foo; - use self::foo::Bar; - - //- /foo/mod.rs - pub struct Bar; - ", - crate_graph! { - "my_library": ("/my_library.rs", []), - }, - ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Bar: t v - "###); -} - -#[test] -fn module_resolution_works_for_raw_modules() { - let map = def_map_with_crate_graph( - " - //- /library.rs - mod r#async; - use self::r#async::Bar; - - //- /async.rs - pub struct Bar; - ", - crate_graph! { - "library": ("/library.rs", []), - }, - ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮async: t - ⋮ - ⋮crate::async - ⋮Bar: t v - "###); -} - -#[test] -fn module_resolution_decl_path() { - let map = def_map_with_crate_graph( - r###" - //- /library.rs - #[path = "bar/baz/foo.rs"] - mod foo; - use self::foo::Bar; - - //- /bar/baz/foo.rs - pub struct Bar; - "###, - crate_graph! { - "library": ("/library.rs", []), - }, - ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮Bar: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Bar: t v - "###); -} - -#[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"] - pub mod bar; - - use self::bar::Baz; - - //- /foo/baz.rs - pub struct Baz; - "###, - crate_graph! { - "main": ("/main.rs", []), - }, - ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[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"] - pub mod bar; - - use self::bar::Baz; - - //- /baz.rs - pub struct Baz; - "###, - crate_graph! { - "main": ("/main.rs", []), - }, - ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[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!(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!(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!(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!(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!(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!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "###); -} - -#[test] -fn module_resolution_decl_inside_inline_module_with_path_attribute() { - 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!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[test] -fn module_resolution_decl_inside_inline_module() { - let map = def_map_with_crate_graph( - r###" - //- /main.rs - mod foo { - mod bar; - } - - //- /foo/bar.rs - pub struct Baz; - "###, - crate_graph! { - "main": ("/main.rs", []), - }, - ); - - assert_snapshot!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[test] -fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { - 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!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[test] -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!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[test] -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; - } - - //- /foo/users.rs - pub struct Baz; - "###, - crate_graph! { - "main": ("/main.rs", []), - }, - ); - - assert_snapshot!(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!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮Baz: t v - "###); -} - -#[test] -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!(map, @r###" - ⋮crate - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[test] -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!(map, @r###" - ⋮crate - ⋮Baz: t v - ⋮foo: t - ⋮ - ⋮crate::foo - ⋮bar: t - ⋮ - ⋮crate::foo::bar - ⋮Baz: t v - "###); -} - -#[test] -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!(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 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; - - //- /bar/qwe.rs - pub struct Baz; - "###, - crate_graph! { - "main": ("/main.rs", []), - }, - ); - - assert_snapshot!(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 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!(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( - r" - //- /lib.rs - mod foo; - mod bar; - mod baz {} - //- /foo.rs - ", - ) - .diagnostics(); - - assert_snapshot!(diagnostics, @r###" - "mod bar;": unresolved module - "### - ); -} -- cgit v1.2.3