diff options
Diffstat (limited to 'crates/ra_hir/src/nameres')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 77 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/mod_resolution.rs | 228 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/raw.rs | 53 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests.rs | 13 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/incremental.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/macros.rs | 29 | ||||
-rw-r--r-- | crates/ra_hir/src/nameres/tests/mod_resolution.rs | 214 |
7 files changed, 262 insertions, 354 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index cef2dc9d2..b5fe16bfa 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -7,14 +7,13 @@ use rustc_hash::FxHashMap; | |||
7 | use test_utils::tested_by; | 7 | use test_utils::tested_by; |
8 | 8 | ||
9 | use crate::{ | 9 | use crate::{ |
10 | attr::Attr, | ||
10 | db::DefDatabase, | 11 | db::DefDatabase, |
11 | ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, | 12 | ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, |
12 | name::MACRO_RULES, | 13 | name::MACRO_RULES, |
13 | nameres::{ | 14 | nameres::{ |
14 | diagnostics::DefDiagnostic, | 15 | diagnostics::DefDiagnostic, mod_resolution::ModDir, raw, Crate, CrateDefMap, CrateModuleId, |
15 | mod_resolution::{resolve_submodule, ParentModule}, | 16 | ModuleData, ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode, |
16 | raw, Crate, CrateDefMap, CrateModuleId, ModuleData, ModuleDef, PerNs, ReachedFixedPoint, | ||
17 | Resolution, ResolveMode, | ||
18 | }, | 17 | }, |
19 | Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, | 18 | Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, |
20 | Struct, Trait, TypeAlias, Union, | 19 | Struct, Trait, TypeAlias, Union, |
@@ -45,6 +44,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C | |||
45 | glob_imports: FxHashMap::default(), | 44 | glob_imports: FxHashMap::default(), |
46 | unresolved_imports: Vec::new(), | 45 | unresolved_imports: Vec::new(), |
47 | unexpanded_macros: Vec::new(), | 46 | unexpanded_macros: Vec::new(), |
47 | mod_dirs: FxHashMap::default(), | ||
48 | macro_stack_monitor: MacroStackMonitor::default(), | 48 | macro_stack_monitor: MacroStackMonitor::default(), |
49 | cfg_options, | 49 | cfg_options, |
50 | }; | 50 | }; |
@@ -87,6 +87,7 @@ struct DefCollector<'a, DB> { | |||
87 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, | 87 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, |
88 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, | 88 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, |
89 | unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, | 89 | unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, |
90 | mod_dirs: FxHashMap<CrateModuleId, ModDir>, | ||
90 | 91 | ||
91 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly | 92 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly |
92 | /// To prevent stack overflow, we add a deep counter here for prevent that. | 93 | /// To prevent stack overflow, we add a deep counter here for prevent that. |
@@ -107,11 +108,10 @@ where | |||
107 | self.def_map.modules[module_id].definition = Some(file_id); | 108 | self.def_map.modules[module_id].definition = Some(file_id); |
108 | ModCollector { | 109 | ModCollector { |
109 | def_collector: &mut *self, | 110 | def_collector: &mut *self, |
110 | attr_path: None, | ||
111 | module_id, | 111 | module_id, |
112 | file_id: file_id.into(), | 112 | file_id: file_id.into(), |
113 | raw_items: &raw_items, | 113 | raw_items: &raw_items, |
114 | parent_module: None, | 114 | mod_dir: ModDir::root(), |
115 | } | 115 | } |
116 | .collect(raw_items.items()); | 116 | .collect(raw_items.items()); |
117 | 117 | ||
@@ -481,13 +481,13 @@ where | |||
481 | if !self.macro_stack_monitor.is_poison(macro_def_id) { | 481 | if !self.macro_stack_monitor.is_poison(macro_def_id) { |
482 | let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items); | 482 | let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items); |
483 | let raw_items = self.db.raw_items(file_id); | 483 | let raw_items = self.db.raw_items(file_id); |
484 | let mod_dir = self.mod_dirs[&module_id].clone(); | ||
484 | ModCollector { | 485 | ModCollector { |
485 | def_collector: &mut *self, | 486 | def_collector: &mut *self, |
486 | file_id, | 487 | file_id, |
487 | attr_path: None, | ||
488 | module_id, | 488 | module_id, |
489 | raw_items: &raw_items, | 489 | raw_items: &raw_items, |
490 | parent_module: None, | 490 | mod_dir, |
491 | } | 491 | } |
492 | .collect(raw_items.items()); | 492 | .collect(raw_items.items()); |
493 | } else { | 493 | } else { |
@@ -508,9 +508,8 @@ struct ModCollector<'a, D> { | |||
508 | def_collector: D, | 508 | def_collector: D, |
509 | module_id: CrateModuleId, | 509 | module_id: CrateModuleId, |
510 | file_id: HirFileId, | 510 | file_id: HirFileId, |
511 | attr_path: Option<&'a SmolStr>, | ||
512 | raw_items: &'a raw::RawItems, | 511 | raw_items: &'a raw::RawItems, |
513 | parent_module: Option<ParentModule<'a>>, | 512 | mod_dir: ModDir, |
514 | } | 513 | } |
515 | 514 | ||
516 | impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> | 515 | impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> |
@@ -518,6 +517,10 @@ where | |||
518 | DB: DefDatabase, | 517 | DB: DefDatabase, |
519 | { | 518 | { |
520 | fn collect(&mut self, items: &[raw::RawItem]) { | 519 | fn collect(&mut self, items: &[raw::RawItem]) { |
520 | // Note: don't assert that inserted value is fresh: it's simply not true | ||
521 | // for macros. | ||
522 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); | ||
523 | |||
521 | // Prelude module is always considered to be `#[macro_use]`. | 524 | // Prelude module is always considered to be `#[macro_use]`. |
522 | if let Some(prelude_module) = self.def_collector.def_map.prelude { | 525 | if let Some(prelude_module) = self.def_collector.def_map.prelude { |
523 | if prelude_module.krate != self.def_collector.def_map.krate { | 526 | if prelude_module.krate != self.def_collector.def_map.krate { |
@@ -530,7 +533,7 @@ where | |||
530 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting | 533 | // `#[macro_use] extern crate` is hoisted to imports macros before collecting |
531 | // any other items. | 534 | // any other items. |
532 | for item in items { | 535 | for item in items { |
533 | if self.is_cfg_enabled(&item.attrs) { | 536 | if self.is_cfg_enabled(item.attrs()) { |
534 | if let raw::RawItemKind::Import(import_id) = item.kind { | 537 | if let raw::RawItemKind::Import(import_id) = item.kind { |
535 | let import = self.raw_items[import_id].clone(); | 538 | let import = self.raw_items[import_id].clone(); |
536 | if import.is_extern_crate && import.is_macro_use { | 539 | if import.is_extern_crate && import.is_macro_use { |
@@ -541,9 +544,11 @@ where | |||
541 | } | 544 | } |
542 | 545 | ||
543 | for item in items { | 546 | for item in items { |
544 | if self.is_cfg_enabled(&item.attrs) { | 547 | if self.is_cfg_enabled(item.attrs()) { |
545 | match item.kind { | 548 | match item.kind { |
546 | raw::RawItemKind::Module(m) => self.collect_module(&self.raw_items[m]), | 549 | raw::RawItemKind::Module(m) => { |
550 | self.collect_module(&self.raw_items[m], item.attrs()) | ||
551 | } | ||
547 | raw::RawItemKind::Import(import_id) => self | 552 | raw::RawItemKind::Import(import_id) => self |
548 | .def_collector | 553 | .def_collector |
549 | .unresolved_imports | 554 | .unresolved_imports |
@@ -555,53 +560,48 @@ where | |||
555 | } | 560 | } |
556 | } | 561 | } |
557 | 562 | ||
558 | fn collect_module(&mut self, module: &raw::ModuleData) { | 563 | fn collect_module(&mut self, module: &raw::ModuleData, attrs: &[Attr]) { |
564 | let path_attr = self.path_attr(attrs); | ||
565 | let is_macro_use = self.is_macro_use(attrs); | ||
559 | match module { | 566 | match module { |
560 | // inline module, just recurse | 567 | // inline module, just recurse |
561 | raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => { | 568 | raw::ModuleData::Definition { name, items, ast_id } => { |
562 | let module_id = | 569 | let module_id = |
563 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); | 570 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); |
564 | let parent_module = ParentModule { name, attr_path: attr_path.as_ref() }; | ||
565 | 571 | ||
566 | ModCollector { | 572 | ModCollector { |
567 | def_collector: &mut *self.def_collector, | 573 | def_collector: &mut *self.def_collector, |
568 | module_id, | 574 | module_id, |
569 | attr_path: attr_path.as_ref(), | ||
570 | file_id: self.file_id, | 575 | file_id: self.file_id, |
571 | raw_items: self.raw_items, | 576 | raw_items: self.raw_items, |
572 | parent_module: Some(parent_module), | 577 | mod_dir: self.mod_dir.descend_into_definition(name, path_attr), |
573 | } | 578 | } |
574 | .collect(&*items); | 579 | .collect(&*items); |
575 | if *is_macro_use { | 580 | if is_macro_use { |
576 | self.import_all_legacy_macros(module_id); | 581 | self.import_all_legacy_macros(module_id); |
577 | } | 582 | } |
578 | } | 583 | } |
579 | // out of line module, resolve, parse and recurse | 584 | // out of line module, resolve, parse and recurse |
580 | raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => { | 585 | raw::ModuleData::Declaration { name, ast_id } => { |
581 | let ast_id = ast_id.with_file_id(self.file_id); | 586 | let ast_id = ast_id.with_file_id(self.file_id); |
582 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); | 587 | match self.mod_dir.resolve_declaration( |
583 | match resolve_submodule( | ||
584 | self.def_collector.db, | 588 | self.def_collector.db, |
585 | self.file_id, | 589 | self.file_id, |
586 | self.attr_path, | ||
587 | name, | 590 | name, |
588 | is_root, | 591 | path_attr, |
589 | attr_path.as_ref(), | ||
590 | self.parent_module, | ||
591 | ) { | 592 | ) { |
592 | Ok(file_id) => { | 593 | Ok((file_id, mod_dir)) => { |
593 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); | 594 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); |
594 | let raw_items = self.def_collector.db.raw_items(file_id.into()); | 595 | let raw_items = self.def_collector.db.raw_items(file_id.into()); |
595 | ModCollector { | 596 | ModCollector { |
596 | def_collector: &mut *self.def_collector, | 597 | def_collector: &mut *self.def_collector, |
597 | module_id, | 598 | module_id, |
598 | attr_path: attr_path.as_ref(), | ||
599 | file_id: file_id.into(), | 599 | file_id: file_id.into(), |
600 | raw_items: &raw_items, | 600 | raw_items: &raw_items, |
601 | parent_module: None, | 601 | mod_dir, |
602 | } | 602 | } |
603 | .collect(raw_items.items()); | 603 | .collect(raw_items.items()); |
604 | if *is_macro_use { | 604 | if is_macro_use { |
605 | self.import_all_legacy_macros(module_id); | 605 | self.import_all_legacy_macros(module_id); |
606 | } | 606 | } |
607 | } | 607 | } |
@@ -714,12 +714,16 @@ where | |||
714 | } | 714 | } |
715 | } | 715 | } |
716 | 716 | ||
717 | fn is_cfg_enabled(&self, attrs: &raw::Attrs) -> bool { | 717 | fn is_cfg_enabled(&self, attrs: &[Attr]) -> bool { |
718 | attrs.as_ref().map_or(true, |attrs| { | 718 | attrs.iter().all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) |
719 | attrs | 719 | } |
720 | .iter() | 720 | |
721 | .all(|attr| attr.is_cfg_enabled(&self.def_collector.cfg_options) != Some(false)) | 721 | fn path_attr<'a>(&self, attrs: &'a [Attr]) -> Option<&'a SmolStr> { |
722 | }) | 722 | attrs.iter().find_map(|attr| attr.as_path()) |
723 | } | ||
724 | |||
725 | fn is_macro_use<'a>(&self, attrs: &'a [Attr]) -> bool { | ||
726 | attrs.iter().any(|attr| attr.is_simple_atom("macro_use")) | ||
723 | } | 727 | } |
724 | } | 728 | } |
725 | 729 | ||
@@ -747,6 +751,7 @@ mod tests { | |||
747 | glob_imports: FxHashMap::default(), | 751 | glob_imports: FxHashMap::default(), |
748 | unresolved_imports: Vec::new(), | 752 | unresolved_imports: Vec::new(), |
749 | unexpanded_macros: Vec::new(), | 753 | unexpanded_macros: Vec::new(), |
754 | mod_dirs: FxHashMap::default(), | ||
750 | macro_stack_monitor: monitor, | 755 | macro_stack_monitor: monitor, |
751 | cfg_options: &CfgOptions::default(), | 756 | cfg_options: &CfgOptions::default(), |
752 | }; | 757 | }; |
diff --git a/crates/ra_hir/src/nameres/mod_resolution.rs b/crates/ra_hir/src/nameres/mod_resolution.rs index 3aa32bd66..e8b808514 100644 --- a/crates/ra_hir/src/nameres/mod_resolution.rs +++ b/crates/ra_hir/src/nameres/mod_resolution.rs | |||
@@ -1,187 +1,87 @@ | |||
1 | //! This module resolves `mod foo;` declaration to file. | 1 | //! This module resolves `mod foo;` declaration to file. |
2 | 2 | use ra_db::FileId; | |
3 | use std::{borrow::Cow, sync::Arc}; | ||
4 | |||
5 | use ra_db::{FileId, SourceRoot}; | ||
6 | use ra_syntax::SmolStr; | 3 | use ra_syntax::SmolStr; |
7 | use relative_path::RelativePathBuf; | 4 | use relative_path::RelativePathBuf; |
8 | 5 | ||
9 | use crate::{db::DefDatabase, HirFileId, Name}; | 6 | use crate::{db::DefDatabase, HirFileId, Name}; |
10 | 7 | ||
11 | #[derive(Clone, Copy)] | 8 | #[derive(Clone, Debug)] |
12 | pub(super) struct ParentModule<'a> { | 9 | pub(super) struct ModDir { |
13 | pub(super) name: &'a Name, | 10 | /// `.` for `mod.rs`, `lib.rs` |
14 | pub(super) attr_path: Option<&'a SmolStr>, | 11 | /// `./foo` for `foo.rs` |
12 | /// `./foo/bar` for `mod bar { mod x; }` nested in `foo.rs` | ||
13 | path: RelativePathBuf, | ||
14 | /// inside `./foo.rs`, mods with `#[path]` should *not* be relative to `./foo/` | ||
15 | root_non_dir_owner: bool, | ||
15 | } | 16 | } |
16 | 17 | ||
17 | impl<'a> ParentModule<'a> { | 18 | impl ModDir { |
18 | fn attribute_path(&self) -> Option<&SmolStr> { | 19 | pub(super) fn root() -> ModDir { |
19 | self.attr_path.filter(|p| !p.is_empty()) | 20 | ModDir { path: RelativePathBuf::default(), root_non_dir_owner: false } |
20 | } | 21 | } |
21 | } | ||
22 | 22 | ||
23 | pub(super) fn resolve_submodule( | 23 | pub(super) fn descend_into_definition( |
24 | db: &impl DefDatabase, | 24 | &self, |
25 | file_id: HirFileId, | 25 | name: &Name, |
26 | mod_attr_path: Option<&SmolStr>, | 26 | attr_path: Option<&SmolStr>, |
27 | name: &Name, | 27 | ) -> ModDir { |
28 | is_root: bool, | 28 | let mut path = self.path.clone(); |
29 | attr_path: Option<&SmolStr>, | 29 | match attr_to_path(attr_path) { |
30 | parent_module: Option<ParentModule<'_>>, | 30 | None => path.push(&name.to_string()), |
31 | ) -> Result<FileId, RelativePathBuf> { | 31 | Some(attr_path) => { |
32 | let file_id = file_id.original_file(db); | 32 | if self.root_non_dir_owner { |
33 | let source_root_id = db.file_source_root(file_id); | 33 | // Workaround for relative path API: turn `lib.rs` into ``. |
34 | let path = db.file_relative_path(file_id); | 34 | if !path.pop() { |
35 | let root = RelativePathBuf::default(); | 35 | path = RelativePathBuf::default(); |
36 | let dir_path = path.parent().unwrap_or(&root); | 36 | } |
37 | let mod_name = path.file_stem().unwrap_or("unknown"); | ||
38 | |||
39 | let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) { | ||
40 | (Some(file_path), Some(parent_module)) => { | ||
41 | let file_path = normalize_attribute_path(file_path); | ||
42 | match parent_module.attribute_path() { | ||
43 | Some(parent_module_attr_path) => { | ||
44 | let path = dir_path | ||
45 | .join(format!( | ||
46 | "{}/{}", | ||
47 | normalize_attribute_path(parent_module_attr_path), | ||
48 | file_path | ||
49 | )) | ||
50 | .normalize(); | ||
51 | ResolutionMode::InlineModuleWithAttributePath( | ||
52 | InsideInlineModuleMode::WithAttributePath(path), | ||
53 | ) | ||
54 | } | ||
55 | None => { | ||
56 | let path = | ||
57 | dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize(); | ||
58 | ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath( | ||
59 | path, | ||
60 | )) | ||
61 | } | 37 | } |
38 | path.push(attr_path); | ||
62 | } | 39 | } |
63 | } | 40 | } |
64 | (None, Some(parent_module)) => match parent_module.attribute_path() { | 41 | ModDir { path, root_non_dir_owner: false } |
65 | Some(parent_module_attr_path) => { | 42 | } |
66 | let path = dir_path.join(format!( | 43 | |
67 | "{}/{}.rs", | 44 | pub(super) fn resolve_declaration( |
68 | normalize_attribute_path(parent_module_attr_path), | 45 | &self, |
69 | name | 46 | db: &impl DefDatabase, |
70 | )); | 47 | file_id: HirFileId, |
71 | ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path)) | 48 | name: &Name, |
49 | attr_path: Option<&SmolStr>, | ||
50 | ) -> Result<(FileId, ModDir), RelativePathBuf> { | ||
51 | let empty_path = RelativePathBuf::default(); | ||
52 | let file_id = file_id.original_file(db); | ||
53 | |||
54 | let mut candidate_files = Vec::new(); | ||
55 | match attr_to_path(attr_path) { | ||
56 | Some(attr_path) => { | ||
57 | let base = if self.root_non_dir_owner { | ||
58 | self.path.parent().unwrap_or(&empty_path) | ||
59 | } else { | ||
60 | &self.path | ||
61 | }; | ||
62 | candidate_files.push(base.join(attr_path)) | ||
72 | } | 63 | } |
73 | None => { | 64 | None => { |
74 | let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name)); | 65 | candidate_files.push(self.path.join(&format!("{}.rs", name))); |
75 | ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path)) | 66 | candidate_files.push(self.path.join(&format!("{}/mod.rs", name))); |
76 | } | ||
77 | }, | ||
78 | (Some(file_path), None) => { | ||
79 | let file_path = normalize_attribute_path(file_path); | ||
80 | let path = dir_path.join(file_path.as_ref()).normalize(); | ||
81 | ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path)) | ||
82 | } | ||
83 | (None, None) => { | ||
84 | let is_dir_owner = is_root || mod_name == "mod" || mod_attr_path.is_some(); | ||
85 | if is_dir_owner { | ||
86 | let file_mod = dir_path.join(format!("{}.rs", name)); | ||
87 | let dir_mod = dir_path.join(format!("{}/mod.rs", name)); | ||
88 | ResolutionMode::OutOfLine(OutOfLineMode::RootOrModRs { | ||
89 | file: file_mod, | ||
90 | directory: dir_mod, | ||
91 | }) | ||
92 | } else { | ||
93 | let path = dir_path.join(format!("{}/{}.rs", mod_name, name)); | ||
94 | ResolutionMode::OutOfLine(OutOfLineMode::FileInDirectory(path)) | ||
95 | } | 67 | } |
96 | } | 68 | }; |
97 | }; | 69 | |
98 | 70 | for candidate in candidate_files.iter() { | |
99 | resolve_mode.resolve(db.source_root(source_root_id)) | 71 | if let Some(file_id) = db.resolve_relative_path(file_id, candidate) { |
100 | } | 72 | let mut root_non_dir_owner = false; |
101 | 73 | let mut mod_path = RelativePathBuf::new(); | |
102 | fn normalize_attribute_path(file_path: &SmolStr) -> Cow<str> { | 74 | if !(candidate.ends_with("mod.rs") || attr_path.is_some()) { |
103 | let current_dir = "./"; | 75 | root_non_dir_owner = true; |
104 | let windows_path_separator = r#"\"#; | 76 | mod_path.push(&name.to_string()); |
105 | let current_dir_normalize = if file_path.starts_with(current_dir) { | ||
106 | &file_path[current_dir.len()..] | ||
107 | } else { | ||
108 | file_path.as_str() | ||
109 | }; | ||
110 | if current_dir_normalize.contains(windows_path_separator) { | ||
111 | Cow::Owned(current_dir_normalize.replace(windows_path_separator, "/")) | ||
112 | } else { | ||
113 | Cow::Borrowed(current_dir_normalize) | ||
114 | } | ||
115 | } | ||
116 | |||
117 | enum OutOfLineMode { | ||
118 | RootOrModRs { file: RelativePathBuf, directory: RelativePathBuf }, | ||
119 | FileInDirectory(RelativePathBuf), | ||
120 | WithAttributePath(RelativePathBuf), | ||
121 | } | ||
122 | |||
123 | impl OutOfLineMode { | ||
124 | pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> { | ||
125 | match self { | ||
126 | OutOfLineMode::RootOrModRs { file, directory } => { | ||
127 | match source_root.file_by_relative_path(file) { | ||
128 | None => resolve_simple_path(source_root, directory).map_err(|_| file.clone()), | ||
129 | file_id => resolve_find_result(file_id, file), | ||
130 | } | 77 | } |
78 | return Ok((file_id, ModDir { path: mod_path, root_non_dir_owner })); | ||
131 | } | 79 | } |
132 | OutOfLineMode::FileInDirectory(path) => resolve_simple_path(source_root, path), | ||
133 | OutOfLineMode::WithAttributePath(path) => resolve_simple_path(source_root, path), | ||
134 | } | 80 | } |
81 | Err(candidate_files.remove(0)) | ||
135 | } | 82 | } |
136 | } | 83 | } |
137 | 84 | ||
138 | enum InsideInlineModuleMode { | 85 | fn attr_to_path(attr: Option<&SmolStr>) -> Option<RelativePathBuf> { |
139 | File(RelativePathBuf), | 86 | attr.and_then(|it| RelativePathBuf::from_path(&it.replace("\\", "/")).ok()) |
140 | WithAttributePath(RelativePathBuf), | ||
141 | } | ||
142 | |||
143 | impl InsideInlineModuleMode { | ||
144 | pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> { | ||
145 | match self { | ||
146 | InsideInlineModuleMode::File(path) => resolve_simple_path(source_root, path), | ||
147 | InsideInlineModuleMode::WithAttributePath(path) => { | ||
148 | resolve_simple_path(source_root, path) | ||
149 | } | ||
150 | } | ||
151 | } | ||
152 | } | ||
153 | |||
154 | enum ResolutionMode { | ||
155 | OutOfLine(OutOfLineMode), | ||
156 | InsideInlineModule(InsideInlineModuleMode), | ||
157 | InlineModuleWithAttributePath(InsideInlineModuleMode), | ||
158 | } | ||
159 | |||
160 | impl ResolutionMode { | ||
161 | pub fn resolve(&self, source_root: Arc<SourceRoot>) -> Result<FileId, RelativePathBuf> { | ||
162 | use self::ResolutionMode::*; | ||
163 | |||
164 | match self { | ||
165 | OutOfLine(mode) => mode.resolve(source_root), | ||
166 | InsideInlineModule(mode) => mode.resolve(source_root), | ||
167 | InlineModuleWithAttributePath(mode) => mode.resolve(source_root), | ||
168 | } | ||
169 | } | ||
170 | } | ||
171 | |||
172 | fn resolve_simple_path( | ||
173 | source_root: Arc<SourceRoot>, | ||
174 | path: &RelativePathBuf, | ||
175 | ) -> Result<FileId, RelativePathBuf> { | ||
176 | resolve_find_result(source_root.file_by_relative_path(path), path) | ||
177 | } | ||
178 | |||
179 | fn resolve_find_result( | ||
180 | file_id: Option<FileId>, | ||
181 | path: &RelativePathBuf, | ||
182 | ) -> Result<FileId, RelativePathBuf> { | ||
183 | match file_id { | ||
184 | Some(file_id) => Ok(file_id.clone()), | ||
185 | None => Err(path.clone()), | ||
186 | } | ||
187 | } | 87 | } |
diff --git a/crates/ra_hir/src/nameres/raw.rs b/crates/ra_hir/src/nameres/raw.rs index 623b343c4..57f2929c3 100644 --- a/crates/ra_hir/src/nameres/raw.rs +++ b/crates/ra_hir/src/nameres/raw.rs | |||
@@ -5,7 +5,7 @@ use std::{ops::Index, sync::Arc}; | |||
5 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; | 5 | use ra_arena::{impl_arena_id, map::ArenaMap, Arena, RawId}; |
6 | use ra_syntax::{ | 6 | use ra_syntax::{ |
7 | ast::{self, AttrsOwner, NameOwner}, | 7 | ast::{self, AttrsOwner, NameOwner}, |
8 | AstNode, AstPtr, SmolStr, SourceFile, | 8 | AstNode, AstPtr, SourceFile, |
9 | }; | 9 | }; |
10 | use test_utils::tested_by; | 10 | use test_utils::tested_by; |
11 | 11 | ||
@@ -121,14 +121,20 @@ impl Index<Macro> for RawItems { | |||
121 | } | 121 | } |
122 | 122 | ||
123 | // Avoid heap allocation on items without attributes. | 123 | // Avoid heap allocation on items without attributes. |
124 | pub(super) type Attrs = Option<Arc<[Attr]>>; | 124 | type Attrs = Option<Arc<[Attr]>>; |
125 | 125 | ||
126 | #[derive(Debug, PartialEq, Eq, Clone)] | 126 | #[derive(Debug, PartialEq, Eq, Clone)] |
127 | pub(super) struct RawItem { | 127 | pub(super) struct RawItem { |
128 | pub(super) attrs: Attrs, | 128 | attrs: Attrs, |
129 | pub(super) kind: RawItemKind, | 129 | pub(super) kind: RawItemKind, |
130 | } | 130 | } |
131 | 131 | ||
132 | impl RawItem { | ||
133 | pub(super) fn attrs(&self) -> &[Attr] { | ||
134 | self.attrs.as_ref().map_or(&[], |it| &*it) | ||
135 | } | ||
136 | } | ||
137 | |||
132 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] | 138 | #[derive(Debug, PartialEq, Eq, Clone, Copy)] |
133 | pub(super) enum RawItemKind { | 139 | pub(super) enum RawItemKind { |
134 | Module(Module), | 140 | Module(Module), |
@@ -143,19 +149,8 @@ impl_arena_id!(Module); | |||
143 | 149 | ||
144 | #[derive(Debug, PartialEq, Eq)] | 150 | #[derive(Debug, PartialEq, Eq)] |
145 | pub(super) enum ModuleData { | 151 | pub(super) enum ModuleData { |
146 | Declaration { | 152 | Declaration { name: Name, ast_id: FileAstId<ast::Module> }, |
147 | name: Name, | 153 | Definition { name: Name, ast_id: FileAstId<ast::Module>, items: Vec<RawItem> }, |
148 | ast_id: FileAstId<ast::Module>, | ||
149 | attr_path: Option<SmolStr>, | ||
150 | is_macro_use: bool, | ||
151 | }, | ||
152 | Definition { | ||
153 | name: Name, | ||
154 | ast_id: FileAstId<ast::Module>, | ||
155 | items: Vec<RawItem>, | ||
156 | attr_path: Option<SmolStr>, | ||
157 | is_macro_use: bool, | ||
158 | }, | ||
159 | } | 154 | } |
160 | 155 | ||
161 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | 156 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] |
@@ -286,28 +281,17 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> { | |||
286 | let attrs = self.parse_attrs(&module); | 281 | let attrs = self.parse_attrs(&module); |
287 | 282 | ||
288 | let ast_id = self.source_ast_id_map.ast_id(&module); | 283 | let ast_id = self.source_ast_id_map.ast_id(&module); |
289 | // FIXME: cfg_attr | ||
290 | let is_macro_use = module.has_atom_attr("macro_use"); | ||
291 | if module.has_semi() { | 284 | if module.has_semi() { |
292 | let attr_path = extract_mod_path_attribute(&module); | 285 | let item = self.raw_items.modules.alloc(ModuleData::Declaration { name, ast_id }); |
293 | let item = self.raw_items.modules.alloc(ModuleData::Declaration { | ||
294 | name, | ||
295 | ast_id, | ||
296 | attr_path, | ||
297 | is_macro_use, | ||
298 | }); | ||
299 | self.push_item(current_module, attrs, RawItemKind::Module(item)); | 286 | self.push_item(current_module, attrs, RawItemKind::Module(item)); |
300 | return; | 287 | return; |
301 | } | 288 | } |
302 | 289 | ||
303 | if let Some(item_list) = module.item_list() { | 290 | if let Some(item_list) = module.item_list() { |
304 | let attr_path = extract_mod_path_attribute(&module); | ||
305 | let item = self.raw_items.modules.alloc(ModuleData::Definition { | 291 | let item = self.raw_items.modules.alloc(ModuleData::Definition { |
306 | name, | 292 | name, |
307 | ast_id, | 293 | ast_id, |
308 | items: Vec::new(), | 294 | items: Vec::new(), |
309 | attr_path, | ||
310 | is_macro_use, | ||
311 | }); | 295 | }); |
312 | self.process_module(Some(item), item_list); | 296 | self.process_module(Some(item), item_list); |
313 | self.push_item(current_module, attrs, RawItemKind::Module(item)); | 297 | self.push_item(current_module, attrs, RawItemKind::Module(item)); |
@@ -417,16 +401,3 @@ impl<DB: AstDatabase> RawItemsCollector<&DB> { | |||
417 | Attr::from_attrs_owner(self.file_id, item, self.db) | 401 | Attr::from_attrs_owner(self.file_id, item, self.db) |
418 | } | 402 | } |
419 | } | 403 | } |
420 | |||
421 | fn extract_mod_path_attribute(module: &ast::Module) -> Option<SmolStr> { | ||
422 | module.attrs().into_iter().find_map(|attr| { | ||
423 | attr.as_simple_key_value().and_then(|(name, value)| { | ||
424 | let is_path = name == "path"; | ||
425 | if is_path { | ||
426 | Some(value) | ||
427 | } else { | ||
428 | None | ||
429 | } | ||
430 | }) | ||
431 | }) | ||
432 | } | ||
diff --git a/crates/ra_hir/src/nameres/tests.rs b/crates/ra_hir/src/nameres/tests.rs index 34dd79574..8c6b40aaf 100644 --- a/crates/ra_hir/src/nameres/tests.rs +++ b/crates/ra_hir/src/nameres/tests.rs | |||
@@ -7,7 +7,6 @@ mod mod_resolution; | |||
7 | use std::sync::Arc; | 7 | use std::sync::Arc; |
8 | 8 | ||
9 | use insta::assert_snapshot; | 9 | use insta::assert_snapshot; |
10 | use ra_cfg::CfgOptions; | ||
11 | use ra_db::SourceDatabase; | 10 | use ra_db::SourceDatabase; |
12 | use test_utils::covers; | 11 | use test_utils::covers; |
13 | 12 | ||
@@ -561,12 +560,12 @@ fn cfg_test() { | |||
561 | "#, | 560 | "#, |
562 | crate_graph! { | 561 | crate_graph! { |
563 | "main": ("/main.rs", ["std"]), | 562 | "main": ("/main.rs", ["std"]), |
564 | "std": ("/lib.rs", [], CfgOptions::default() | 563 | "std": ("/lib.rs", [], cfg = { |
565 | .atom("test".into()) | 564 | "test", |
566 | .key_value("feature".into(), "foo".into()) | 565 | "feature" = "foo", |
567 | .key_value("feature".into(), "bar".into()) | 566 | "feature" = "bar", |
568 | .key_value("opt".into(), "42".into()) | 567 | "opt" = "42", |
569 | ), | 568 | }), |
570 | }, | 569 | }, |
571 | ); | 570 | ); |
572 | 571 | ||
diff --git a/crates/ra_hir/src/nameres/tests/incremental.rs b/crates/ra_hir/src/nameres/tests/incremental.rs index c41862a0b..af9c39760 100644 --- a/crates/ra_hir/src/nameres/tests/incremental.rs +++ b/crates/ra_hir/src/nameres/tests/incremental.rs | |||
@@ -2,7 +2,7 @@ use super::*; | |||
2 | 2 | ||
3 | use std::sync::Arc; | 3 | use std::sync::Arc; |
4 | 4 | ||
5 | use ra_db::SourceDatabase; | 5 | use ra_db::{SourceDatabase, SourceDatabaseExt}; |
6 | 6 | ||
7 | fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) { | 7 | fn check_def_map_is_not_recomputed(initial: &str, file_change: &str) { |
8 | let (mut db, pos) = MockDatabase::with_position(initial); | 8 | let (mut db, pos) = MockDatabase::with_position(initial); |
diff --git a/crates/ra_hir/src/nameres/tests/macros.rs b/crates/ra_hir/src/nameres/tests/macros.rs index e4b408394..4f52ad2c5 100644 --- a/crates/ra_hir/src/nameres/tests/macros.rs +++ b/crates/ra_hir/src/nameres/tests/macros.rs | |||
@@ -38,21 +38,34 @@ fn macro_rules_can_define_modules() { | |||
38 | } | 38 | } |
39 | m!(n1); | 39 | m!(n1); |
40 | 40 | ||
41 | mod m { | ||
42 | m!(n3) | ||
43 | } | ||
44 | |||
41 | //- /n1.rs | 45 | //- /n1.rs |
42 | m!(n2) | 46 | m!(n2) |
43 | //- /n1/n2.rs | 47 | //- /n1/n2.rs |
44 | struct X; | 48 | struct X; |
49 | //- /m/n3.rs | ||
50 | struct Y; | ||
45 | ", | 51 | ", |
46 | ); | 52 | ); |
47 | assert_snapshot!(map, @r###" | 53 | assert_snapshot!(map, @r###" |
48 | ⋮crate | 54 | crate |
49 | ⋮n1: t | 55 | m: t |
50 | ⋮ | 56 | n1: t |
51 | ⋮crate::n1 | 57 | |
52 | ⋮n2: t | 58 | crate::m |
53 | ⋮ | 59 | n3: t |
54 | ⋮crate::n1::n2 | 60 | |
55 | ⋮X: t v | 61 | crate::m::n3 |
62 | Y: t v | ||
63 | |||
64 | crate::n1 | ||
65 | n2: t | ||
66 | |||
67 | crate::n1::n2 | ||
68 | X: t v | ||
56 | "###); | 69 | "###); |
57 | } | 70 | } |
58 | 71 | ||
diff --git a/crates/ra_hir/src/nameres/tests/mod_resolution.rs b/crates/ra_hir/src/nameres/tests/mod_resolution.rs index e3e6f1e95..f569aacdc 100644 --- a/crates/ra_hir/src/nameres/tests/mod_resolution.rs +++ b/crates/ra_hir/src/nameres/tests/mod_resolution.rs | |||
@@ -26,6 +26,33 @@ fn name_res_works_for_broken_modules() { | |||
26 | } | 26 | } |
27 | 27 | ||
28 | #[test] | 28 | #[test] |
29 | fn nested_module_resolution() { | ||
30 | let map = def_map( | ||
31 | " | ||
32 | //- /lib.rs | ||
33 | mod n1; | ||
34 | |||
35 | //- /n1.rs | ||
36 | mod n2; | ||
37 | |||
38 | //- /n1/n2.rs | ||
39 | struct X; | ||
40 | ", | ||
41 | ); | ||
42 | |||
43 | assert_snapshot!(map, @r###" | ||
44 | ⋮crate | ||
45 | ⋮n1: t | ||
46 | ⋮ | ||
47 | ⋮crate::n1 | ||
48 | ⋮n2: t | ||
49 | ⋮ | ||
50 | ⋮crate::n1::n2 | ||
51 | ⋮X: t v | ||
52 | "###); | ||
53 | } | ||
54 | |||
55 | #[test] | ||
29 | fn module_resolution_works_for_non_standard_filenames() { | 56 | fn module_resolution_works_for_non_standard_filenames() { |
30 | let map = def_map_with_crate_graph( | 57 | let map = def_map_with_crate_graph( |
31 | " | 58 | " |
@@ -53,18 +80,15 @@ fn module_resolution_works_for_non_standard_filenames() { | |||
53 | 80 | ||
54 | #[test] | 81 | #[test] |
55 | fn module_resolution_works_for_raw_modules() { | 82 | fn module_resolution_works_for_raw_modules() { |
56 | let map = def_map_with_crate_graph( | 83 | let map = def_map( |
57 | " | 84 | " |
58 | //- /library.rs | 85 | //- /lib.rs |
59 | mod r#async; | 86 | mod r#async; |
60 | use self::r#async::Bar; | 87 | use self::r#async::Bar; |
61 | 88 | ||
62 | //- /async.rs | 89 | //- /async.rs |
63 | pub struct Bar; | 90 | pub struct Bar; |
64 | ", | 91 | ", |
65 | crate_graph! { | ||
66 | "library": ("/library.rs", []), | ||
67 | }, | ||
68 | ); | 92 | ); |
69 | 93 | ||
70 | assert_snapshot!(map, @r###" | 94 | assert_snapshot!(map, @r###" |
@@ -79,9 +103,9 @@ fn module_resolution_works_for_raw_modules() { | |||
79 | 103 | ||
80 | #[test] | 104 | #[test] |
81 | fn module_resolution_decl_path() { | 105 | fn module_resolution_decl_path() { |
82 | let map = def_map_with_crate_graph( | 106 | let map = def_map( |
83 | r###" | 107 | r###" |
84 | //- /library.rs | 108 | //- /lib.rs |
85 | #[path = "bar/baz/foo.rs"] | 109 | #[path = "bar/baz/foo.rs"] |
86 | mod foo; | 110 | mod foo; |
87 | use self::foo::Bar; | 111 | use self::foo::Bar; |
@@ -89,9 +113,6 @@ fn module_resolution_decl_path() { | |||
89 | //- /bar/baz/foo.rs | 113 | //- /bar/baz/foo.rs |
90 | pub struct Bar; | 114 | pub struct Bar; |
91 | "###, | 115 | "###, |
92 | crate_graph! { | ||
93 | "library": ("/library.rs", []), | ||
94 | }, | ||
95 | ); | 116 | ); |
96 | 117 | ||
97 | assert_snapshot!(map, @r###" | 118 | assert_snapshot!(map, @r###" |
@@ -106,7 +127,7 @@ fn module_resolution_decl_path() { | |||
106 | 127 | ||
107 | #[test] | 128 | #[test] |
108 | fn module_resolution_module_with_path_in_mod_rs() { | 129 | fn module_resolution_module_with_path_in_mod_rs() { |
109 | let map = def_map_with_crate_graph( | 130 | let map = def_map( |
110 | r###" | 131 | r###" |
111 | //- /main.rs | 132 | //- /main.rs |
112 | mod foo; | 133 | mod foo; |
@@ -120,9 +141,6 @@ fn module_resolution_module_with_path_in_mod_rs() { | |||
120 | //- /foo/baz.rs | 141 | //- /foo/baz.rs |
121 | pub struct Baz; | 142 | pub struct Baz; |
122 | "###, | 143 | "###, |
123 | crate_graph! { | ||
124 | "main": ("/main.rs", []), | ||
125 | }, | ||
126 | ); | 144 | ); |
127 | 145 | ||
128 | assert_snapshot!(map, @r###" | 146 | assert_snapshot!(map, @r###" |
@@ -140,7 +158,7 @@ fn module_resolution_module_with_path_in_mod_rs() { | |||
140 | 158 | ||
141 | #[test] | 159 | #[test] |
142 | fn module_resolution_module_with_path_non_crate_root() { | 160 | fn module_resolution_module_with_path_non_crate_root() { |
143 | let map = def_map_with_crate_graph( | 161 | let map = def_map( |
144 | r###" | 162 | r###" |
145 | //- /main.rs | 163 | //- /main.rs |
146 | mod foo; | 164 | mod foo; |
@@ -154,9 +172,6 @@ fn module_resolution_module_with_path_non_crate_root() { | |||
154 | //- /baz.rs | 172 | //- /baz.rs |
155 | pub struct Baz; | 173 | pub struct Baz; |
156 | "###, | 174 | "###, |
157 | crate_graph! { | ||
158 | "main": ("/main.rs", []), | ||
159 | }, | ||
160 | ); | 175 | ); |
161 | 176 | ||
162 | assert_snapshot!(map, @r###" | 177 | assert_snapshot!(map, @r###" |
@@ -174,7 +189,7 @@ fn module_resolution_module_with_path_non_crate_root() { | |||
174 | 189 | ||
175 | #[test] | 190 | #[test] |
176 | fn module_resolution_module_decl_path_super() { | 191 | fn module_resolution_module_decl_path_super() { |
177 | let map = def_map_with_crate_graph( | 192 | let map = def_map( |
178 | r###" | 193 | r###" |
179 | //- /main.rs | 194 | //- /main.rs |
180 | #[path = "bar/baz/module.rs"] | 195 | #[path = "bar/baz/module.rs"] |
@@ -184,9 +199,6 @@ fn module_resolution_module_decl_path_super() { | |||
184 | //- /bar/baz/module.rs | 199 | //- /bar/baz/module.rs |
185 | use super::Baz; | 200 | use super::Baz; |
186 | "###, | 201 | "###, |
187 | crate_graph! { | ||
188 | "main": ("/main.rs", []), | ||
189 | }, | ||
190 | ); | 202 | ); |
191 | 203 | ||
192 | assert_snapshot!(map, @r###" | 204 | assert_snapshot!(map, @r###" |
@@ -201,7 +213,7 @@ fn module_resolution_module_decl_path_super() { | |||
201 | 213 | ||
202 | #[test] | 214 | #[test] |
203 | fn module_resolution_explicit_path_mod_rs() { | 215 | fn module_resolution_explicit_path_mod_rs() { |
204 | let map = def_map_with_crate_graph( | 216 | let map = def_map( |
205 | r###" | 217 | r###" |
206 | //- /main.rs | 218 | //- /main.rs |
207 | #[path = "module/mod.rs"] | 219 | #[path = "module/mod.rs"] |
@@ -210,9 +222,6 @@ fn module_resolution_explicit_path_mod_rs() { | |||
210 | //- /module/mod.rs | 222 | //- /module/mod.rs |
211 | pub struct Baz; | 223 | pub struct Baz; |
212 | "###, | 224 | "###, |
213 | crate_graph! { | ||
214 | "main": ("/main.rs", []), | ||
215 | }, | ||
216 | ); | 225 | ); |
217 | 226 | ||
218 | assert_snapshot!(map, @r###" | 227 | assert_snapshot!(map, @r###" |
@@ -226,7 +235,7 @@ fn module_resolution_explicit_path_mod_rs() { | |||
226 | 235 | ||
227 | #[test] | 236 | #[test] |
228 | fn module_resolution_relative_path() { | 237 | fn module_resolution_relative_path() { |
229 | let map = def_map_with_crate_graph( | 238 | let map = def_map( |
230 | r###" | 239 | r###" |
231 | //- /main.rs | 240 | //- /main.rs |
232 | mod foo; | 241 | mod foo; |
@@ -238,9 +247,6 @@ fn module_resolution_relative_path() { | |||
238 | //- /sub.rs | 247 | //- /sub.rs |
239 | pub struct Baz; | 248 | pub struct Baz; |
240 | "###, | 249 | "###, |
241 | crate_graph! { | ||
242 | "main": ("/main.rs", []), | ||
243 | }, | ||
244 | ); | 250 | ); |
245 | 251 | ||
246 | assert_snapshot!(map, @r###" | 252 | assert_snapshot!(map, @r###" |
@@ -257,7 +263,7 @@ fn module_resolution_relative_path() { | |||
257 | 263 | ||
258 | #[test] | 264 | #[test] |
259 | fn module_resolution_relative_path_2() { | 265 | fn module_resolution_relative_path_2() { |
260 | let map = def_map_with_crate_graph( | 266 | let map = def_map( |
261 | r###" | 267 | r###" |
262 | //- /main.rs | 268 | //- /main.rs |
263 | mod foo; | 269 | mod foo; |
@@ -269,9 +275,6 @@ fn module_resolution_relative_path_2() { | |||
269 | //- /sub.rs | 275 | //- /sub.rs |
270 | pub struct Baz; | 276 | pub struct Baz; |
271 | "###, | 277 | "###, |
272 | crate_graph! { | ||
273 | "main": ("/main.rs", []), | ||
274 | }, | ||
275 | ); | 278 | ); |
276 | 279 | ||
277 | assert_snapshot!(map, @r###" | 280 | assert_snapshot!(map, @r###" |
@@ -288,7 +291,7 @@ fn module_resolution_relative_path_2() { | |||
288 | 291 | ||
289 | #[test] | 292 | #[test] |
290 | fn module_resolution_explicit_path_mod_rs_2() { | 293 | fn module_resolution_explicit_path_mod_rs_2() { |
291 | let map = def_map_with_crate_graph( | 294 | let map = def_map( |
292 | r###" | 295 | r###" |
293 | //- /main.rs | 296 | //- /main.rs |
294 | #[path = "module/bar/mod.rs"] | 297 | #[path = "module/bar/mod.rs"] |
@@ -297,9 +300,6 @@ fn module_resolution_explicit_path_mod_rs_2() { | |||
297 | //- /module/bar/mod.rs | 300 | //- /module/bar/mod.rs |
298 | pub struct Baz; | 301 | pub struct Baz; |
299 | "###, | 302 | "###, |
300 | crate_graph! { | ||
301 | "main": ("/main.rs", []), | ||
302 | }, | ||
303 | ); | 303 | ); |
304 | 304 | ||
305 | assert_snapshot!(map, @r###" | 305 | assert_snapshot!(map, @r###" |
@@ -313,7 +313,7 @@ fn module_resolution_explicit_path_mod_rs_2() { | |||
313 | 313 | ||
314 | #[test] | 314 | #[test] |
315 | fn module_resolution_explicit_path_mod_rs_with_win_separator() { | 315 | fn module_resolution_explicit_path_mod_rs_with_win_separator() { |
316 | let map = def_map_with_crate_graph( | 316 | let map = def_map( |
317 | r###" | 317 | r###" |
318 | //- /main.rs | 318 | //- /main.rs |
319 | #[path = "module\bar\mod.rs"] | 319 | #[path = "module\bar\mod.rs"] |
@@ -322,9 +322,6 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() { | |||
322 | //- /module/bar/mod.rs | 322 | //- /module/bar/mod.rs |
323 | pub struct Baz; | 323 | pub struct Baz; |
324 | "###, | 324 | "###, |
325 | crate_graph! { | ||
326 | "main": ("/main.rs", []), | ||
327 | }, | ||
328 | ); | 325 | ); |
329 | 326 | ||
330 | assert_snapshot!(map, @r###" | 327 | assert_snapshot!(map, @r###" |
@@ -338,7 +335,7 @@ fn module_resolution_explicit_path_mod_rs_with_win_separator() { | |||
338 | 335 | ||
339 | #[test] | 336 | #[test] |
340 | fn module_resolution_decl_inside_inline_module_with_path_attribute() { | 337 | fn module_resolution_decl_inside_inline_module_with_path_attribute() { |
341 | let map = def_map_with_crate_graph( | 338 | let map = def_map( |
342 | r###" | 339 | r###" |
343 | //- /main.rs | 340 | //- /main.rs |
344 | #[path = "models"] | 341 | #[path = "models"] |
@@ -349,9 +346,6 @@ fn module_resolution_decl_inside_inline_module_with_path_attribute() { | |||
349 | //- /models/bar.rs | 346 | //- /models/bar.rs |
350 | pub struct Baz; | 347 | pub struct Baz; |
351 | "###, | 348 | "###, |
352 | crate_graph! { | ||
353 | "main": ("/main.rs", []), | ||
354 | }, | ||
355 | ); | 349 | ); |
356 | 350 | ||
357 | assert_snapshot!(map, @r###" | 351 | assert_snapshot!(map, @r###" |
@@ -368,7 +362,7 @@ fn module_resolution_decl_inside_inline_module_with_path_attribute() { | |||
368 | 362 | ||
369 | #[test] | 363 | #[test] |
370 | fn module_resolution_decl_inside_inline_module() { | 364 | fn module_resolution_decl_inside_inline_module() { |
371 | let map = def_map_with_crate_graph( | 365 | let map = def_map( |
372 | r###" | 366 | r###" |
373 | //- /main.rs | 367 | //- /main.rs |
374 | mod foo { | 368 | mod foo { |
@@ -378,9 +372,6 @@ fn module_resolution_decl_inside_inline_module() { | |||
378 | //- /foo/bar.rs | 372 | //- /foo/bar.rs |
379 | pub struct Baz; | 373 | pub struct Baz; |
380 | "###, | 374 | "###, |
381 | crate_graph! { | ||
382 | "main": ("/main.rs", []), | ||
383 | }, | ||
384 | ); | 375 | ); |
385 | 376 | ||
386 | assert_snapshot!(map, @r###" | 377 | assert_snapshot!(map, @r###" |
@@ -397,7 +388,7 @@ fn module_resolution_decl_inside_inline_module() { | |||
397 | 388 | ||
398 | #[test] | 389 | #[test] |
399 | fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { | 390 | fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { |
400 | let map = def_map_with_crate_graph( | 391 | let map = def_map( |
401 | r###" | 392 | r###" |
402 | //- /main.rs | 393 | //- /main.rs |
403 | #[path = "models/db"] | 394 | #[path = "models/db"] |
@@ -408,9 +399,6 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { | |||
408 | //- /models/db/bar.rs | 399 | //- /models/db/bar.rs |
409 | pub struct Baz; | 400 | pub struct Baz; |
410 | "###, | 401 | "###, |
411 | crate_graph! { | ||
412 | "main": ("/main.rs", []), | ||
413 | }, | ||
414 | ); | 402 | ); |
415 | 403 | ||
416 | assert_snapshot!(map, @r###" | 404 | assert_snapshot!(map, @r###" |
@@ -427,7 +415,7 @@ fn module_resolution_decl_inside_inline_module_2_with_path_attribute() { | |||
427 | 415 | ||
428 | #[test] | 416 | #[test] |
429 | fn module_resolution_decl_inside_inline_module_3() { | 417 | fn module_resolution_decl_inside_inline_module_3() { |
430 | let map = def_map_with_crate_graph( | 418 | let map = def_map( |
431 | r###" | 419 | r###" |
432 | //- /main.rs | 420 | //- /main.rs |
433 | #[path = "models/db"] | 421 | #[path = "models/db"] |
@@ -439,9 +427,6 @@ fn module_resolution_decl_inside_inline_module_3() { | |||
439 | //- /models/db/users.rs | 427 | //- /models/db/users.rs |
440 | pub struct Baz; | 428 | pub struct Baz; |
441 | "###, | 429 | "###, |
442 | crate_graph! { | ||
443 | "main": ("/main.rs", []), | ||
444 | }, | ||
445 | ); | 430 | ); |
446 | 431 | ||
447 | assert_snapshot!(map, @r###" | 432 | assert_snapshot!(map, @r###" |
@@ -458,7 +443,7 @@ fn module_resolution_decl_inside_inline_module_3() { | |||
458 | 443 | ||
459 | #[test] | 444 | #[test] |
460 | fn module_resolution_decl_inside_inline_module_empty_path() { | 445 | fn module_resolution_decl_inside_inline_module_empty_path() { |
461 | let map = def_map_with_crate_graph( | 446 | let map = def_map( |
462 | r###" | 447 | r###" |
463 | //- /main.rs | 448 | //- /main.rs |
464 | #[path = ""] | 449 | #[path = ""] |
@@ -467,12 +452,9 @@ fn module_resolution_decl_inside_inline_module_empty_path() { | |||
467 | mod bar; | 452 | mod bar; |
468 | } | 453 | } |
469 | 454 | ||
470 | //- /foo/users.rs | 455 | //- /users.rs |
471 | pub struct Baz; | 456 | pub struct Baz; |
472 | "###, | 457 | "###, |
473 | crate_graph! { | ||
474 | "main": ("/main.rs", []), | ||
475 | }, | ||
476 | ); | 458 | ); |
477 | 459 | ||
478 | assert_snapshot!(map, @r###" | 460 | assert_snapshot!(map, @r###" |
@@ -489,32 +471,25 @@ fn module_resolution_decl_inside_inline_module_empty_path() { | |||
489 | 471 | ||
490 | #[test] | 472 | #[test] |
491 | fn module_resolution_decl_empty_path() { | 473 | fn module_resolution_decl_empty_path() { |
492 | let map = def_map_with_crate_graph( | 474 | let map = def_map( |
493 | r###" | 475 | r###" |
494 | //- /main.rs | 476 | //- /main.rs |
495 | #[path = ""] | 477 | #[path = ""] // Should try to read `/` (a directory) |
496 | mod foo; | 478 | mod foo; |
497 | 479 | ||
498 | //- /foo.rs | 480 | //- /foo.rs |
499 | pub struct Baz; | 481 | pub struct Baz; |
500 | "###, | 482 | "###, |
501 | crate_graph! { | ||
502 | "main": ("/main.rs", []), | ||
503 | }, | ||
504 | ); | 483 | ); |
505 | 484 | ||
506 | assert_snapshot!(map, @r###" | 485 | assert_snapshot!(map, @r###" |
507 | ⋮crate | 486 | ⋮crate |
508 | ⋮foo: t | ||
509 | ⋮ | ||
510 | ⋮crate::foo | ||
511 | ⋮Baz: t v | ||
512 | "###); | 487 | "###); |
513 | } | 488 | } |
514 | 489 | ||
515 | #[test] | 490 | #[test] |
516 | fn module_resolution_decl_inside_inline_module_relative_path() { | 491 | fn module_resolution_decl_inside_inline_module_relative_path() { |
517 | let map = def_map_with_crate_graph( | 492 | let map = def_map( |
518 | r###" | 493 | r###" |
519 | //- /main.rs | 494 | //- /main.rs |
520 | #[path = "./models"] | 495 | #[path = "./models"] |
@@ -525,9 +500,6 @@ fn module_resolution_decl_inside_inline_module_relative_path() { | |||
525 | //- /models/bar.rs | 500 | //- /models/bar.rs |
526 | pub struct Baz; | 501 | pub struct Baz; |
527 | "###, | 502 | "###, |
528 | crate_graph! { | ||
529 | "main": ("/main.rs", []), | ||
530 | }, | ||
531 | ); | 503 | ); |
532 | 504 | ||
533 | assert_snapshot!(map, @r###" | 505 | assert_snapshot!(map, @r###" |
@@ -544,7 +516,7 @@ fn module_resolution_decl_inside_inline_module_relative_path() { | |||
544 | 516 | ||
545 | #[test] | 517 | #[test] |
546 | fn module_resolution_decl_inside_inline_module_in_crate_root() { | 518 | fn module_resolution_decl_inside_inline_module_in_crate_root() { |
547 | let map = def_map_with_crate_graph( | 519 | let map = def_map( |
548 | r###" | 520 | r###" |
549 | //- /main.rs | 521 | //- /main.rs |
550 | mod foo { | 522 | mod foo { |
@@ -556,9 +528,6 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() { | |||
556 | //- /foo/baz.rs | 528 | //- /foo/baz.rs |
557 | pub struct Baz; | 529 | pub struct Baz; |
558 | "###, | 530 | "###, |
559 | crate_graph! { | ||
560 | "main": ("/main.rs", []), | ||
561 | }, | ||
562 | ); | 531 | ); |
563 | 532 | ||
564 | assert_snapshot!(map, @r###" | 533 | assert_snapshot!(map, @r###" |
@@ -576,7 +545,7 @@ fn module_resolution_decl_inside_inline_module_in_crate_root() { | |||
576 | 545 | ||
577 | #[test] | 546 | #[test] |
578 | fn module_resolution_decl_inside_inline_module_in_mod_rs() { | 547 | fn module_resolution_decl_inside_inline_module_in_mod_rs() { |
579 | let map = def_map_with_crate_graph( | 548 | let map = def_map( |
580 | r###" | 549 | r###" |
581 | //- /main.rs | 550 | //- /main.rs |
582 | mod foo; | 551 | mod foo; |
@@ -591,9 +560,6 @@ fn module_resolution_decl_inside_inline_module_in_mod_rs() { | |||
591 | //- /foo/bar/qwe.rs | 560 | //- /foo/bar/qwe.rs |
592 | pub struct Baz; | 561 | pub struct Baz; |
593 | "###, | 562 | "###, |
594 | crate_graph! { | ||
595 | "main": ("/main.rs", []), | ||
596 | }, | ||
597 | ); | 563 | ); |
598 | 564 | ||
599 | assert_snapshot!(map, @r###" | 565 | assert_snapshot!(map, @r###" |
@@ -614,7 +580,7 @@ fn module_resolution_decl_inside_inline_module_in_mod_rs() { | |||
614 | 580 | ||
615 | #[test] | 581 | #[test] |
616 | fn module_resolution_decl_inside_inline_module_in_non_crate_root() { | 582 | fn module_resolution_decl_inside_inline_module_in_non_crate_root() { |
617 | let map = def_map_with_crate_graph( | 583 | let map = def_map( |
618 | r###" | 584 | r###" |
619 | //- /main.rs | 585 | //- /main.rs |
620 | mod foo; | 586 | mod foo; |
@@ -626,12 +592,9 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() { | |||
626 | } | 592 | } |
627 | use self::bar::baz::Baz; | 593 | use self::bar::baz::Baz; |
628 | 594 | ||
629 | //- /bar/qwe.rs | 595 | //- /foo/bar/qwe.rs |
630 | pub struct Baz; | 596 | pub struct Baz; |
631 | "###, | 597 | "###, |
632 | crate_graph! { | ||
633 | "main": ("/main.rs", []), | ||
634 | }, | ||
635 | ); | 598 | ); |
636 | 599 | ||
637 | assert_snapshot!(map, @r###" | 600 | assert_snapshot!(map, @r###" |
@@ -652,7 +615,7 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root() { | |||
652 | 615 | ||
653 | #[test] | 616 | #[test] |
654 | fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { | 617 | fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { |
655 | let map = def_map_with_crate_graph( | 618 | let map = def_map( |
656 | r###" | 619 | r###" |
657 | //- /main.rs | 620 | //- /main.rs |
658 | mod foo; | 621 | mod foo; |
@@ -667,9 +630,6 @@ fn module_resolution_decl_inside_inline_module_in_non_crate_root_2() { | |||
667 | //- /bar/baz.rs | 630 | //- /bar/baz.rs |
668 | pub struct Baz; | 631 | pub struct Baz; |
669 | "###, | 632 | "###, |
670 | crate_graph! { | ||
671 | "main": ("/main.rs", []), | ||
672 | }, | ||
673 | ); | 633 | ); |
674 | 634 | ||
675 | assert_snapshot!(map, @r###" | 635 | assert_snapshot!(map, @r###" |
@@ -709,7 +669,7 @@ fn unresolved_module_diagnostics() { | |||
709 | 669 | ||
710 | #[test] | 670 | #[test] |
711 | fn module_resolution_decl_inside_module_in_non_crate_root_2() { | 671 | fn module_resolution_decl_inside_module_in_non_crate_root_2() { |
712 | let map = def_map_with_crate_graph( | 672 | let map = def_map( |
713 | r###" | 673 | r###" |
714 | //- /main.rs | 674 | //- /main.rs |
715 | #[path="module/m2.rs"] | 675 | #[path="module/m2.rs"] |
@@ -721,9 +681,6 @@ fn module_resolution_decl_inside_module_in_non_crate_root_2() { | |||
721 | //- /module/submod.rs | 681 | //- /module/submod.rs |
722 | pub struct Baz; | 682 | pub struct Baz; |
723 | "###, | 683 | "###, |
724 | crate_graph! { | ||
725 | "main": ("/main.rs", []), | ||
726 | }, | ||
727 | ); | 684 | ); |
728 | 685 | ||
729 | assert_snapshot!(map, @r###" | 686 | assert_snapshot!(map, @r###" |
@@ -737,3 +694,66 @@ fn module_resolution_decl_inside_module_in_non_crate_root_2() { | |||
737 | ⋮Baz: t v | 694 | ⋮Baz: t v |
738 | "###); | 695 | "###); |
739 | } | 696 | } |
697 | |||
698 | #[test] | ||
699 | fn nested_out_of_line_module() { | ||
700 | let map = def_map( | ||
701 | r###" | ||
702 | //- /lib.rs | ||
703 | mod a { | ||
704 | mod b { | ||
705 | mod c; | ||
706 | } | ||
707 | } | ||
708 | |||
709 | //- /a/b/c.rs | ||
710 | struct X; | ||
711 | "###, | ||
712 | ); | ||
713 | |||
714 | assert_snapshot!(map, @r###" | ||
715 | crate | ||
716 | a: t | ||
717 | |||
718 | crate::a | ||
719 | b: t | ||
720 | |||
721 | crate::a::b | ||
722 | c: t | ||
723 | |||
724 | crate::a::b::c | ||
725 | X: t v | ||
726 | "###); | ||
727 | } | ||
728 | |||
729 | #[test] | ||
730 | fn nested_out_of_line_module_with_path() { | ||
731 | let map = def_map( | ||
732 | r###" | ||
733 | //- /lib.rs | ||
734 | mod a { | ||
735 | #[path = "d/e"] | ||
736 | mod b { | ||
737 | mod c; | ||
738 | } | ||
739 | } | ||
740 | |||
741 | //- /a/d/e/c.rs | ||
742 | struct X; | ||
743 | "###, | ||
744 | ); | ||
745 | |||
746 | assert_snapshot!(map, @r###" | ||
747 | crate | ||
748 | a: t | ||
749 | |||
750 | crate::a | ||
751 | b: t | ||
752 | |||
753 | crate::a::b | ||
754 | c: t | ||
755 | |||
756 | crate::a::b::c | ||
757 | X: t v | ||
758 | "###); | ||
759 | } | ||