diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 40 |
1 files changed, 18 insertions, 22 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index cef2dc9d2..88aee7437 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -2,7 +2,7 @@ | |||
2 | 2 | ||
3 | use ra_cfg::CfgOptions; | 3 | use ra_cfg::CfgOptions; |
4 | use ra_db::FileId; | 4 | use ra_db::FileId; |
5 | use ra_syntax::{ast, SmolStr}; | 5 | use ra_syntax::ast; |
6 | use rustc_hash::FxHashMap; | 6 | use rustc_hash::FxHashMap; |
7 | use test_utils::tested_by; | 7 | use test_utils::tested_by; |
8 | 8 | ||
@@ -11,10 +11,8 @@ use crate::{ | |||
11 | ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, | 11 | ids::{AstItemDef, LocationCtx, MacroCallId, MacroCallLoc, MacroDefId, MacroFileKind}, |
12 | name::MACRO_RULES, | 12 | name::MACRO_RULES, |
13 | nameres::{ | 13 | nameres::{ |
14 | diagnostics::DefDiagnostic, | 14 | diagnostics::DefDiagnostic, mod_resolution::ModDir, raw, Crate, CrateDefMap, CrateModuleId, |
15 | mod_resolution::{resolve_submodule, ParentModule}, | 15 | ModuleData, ModuleDef, PerNs, ReachedFixedPoint, Resolution, ResolveMode, |
16 | raw, Crate, CrateDefMap, CrateModuleId, ModuleData, ModuleDef, PerNs, ReachedFixedPoint, | ||
17 | Resolution, ResolveMode, | ||
18 | }, | 16 | }, |
19 | Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, | 17 | Adt, AstId, Const, Enum, Function, HirFileId, MacroDef, Module, Name, Path, PathKind, Static, |
20 | Struct, Trait, TypeAlias, Union, | 18 | Struct, Trait, TypeAlias, Union, |
@@ -45,6 +43,7 @@ pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> C | |||
45 | glob_imports: FxHashMap::default(), | 43 | glob_imports: FxHashMap::default(), |
46 | unresolved_imports: Vec::new(), | 44 | unresolved_imports: Vec::new(), |
47 | unexpanded_macros: Vec::new(), | 45 | unexpanded_macros: Vec::new(), |
46 | mod_dirs: FxHashMap::default(), | ||
48 | macro_stack_monitor: MacroStackMonitor::default(), | 47 | macro_stack_monitor: MacroStackMonitor::default(), |
49 | cfg_options, | 48 | cfg_options, |
50 | }; | 49 | }; |
@@ -87,6 +86,7 @@ struct DefCollector<'a, DB> { | |||
87 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, | 86 | glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, |
88 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, | 87 | unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, |
89 | unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, | 88 | unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>, |
89 | mod_dirs: FxHashMap<CrateModuleId, ModDir>, | ||
90 | 90 | ||
91 | /// Some macro use `$tt:tt which mean we have to handle the macro perfectly | 91 | /// 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. | 92 | /// To prevent stack overflow, we add a deep counter here for prevent that. |
@@ -107,11 +107,10 @@ where | |||
107 | self.def_map.modules[module_id].definition = Some(file_id); | 107 | self.def_map.modules[module_id].definition = Some(file_id); |
108 | ModCollector { | 108 | ModCollector { |
109 | def_collector: &mut *self, | 109 | def_collector: &mut *self, |
110 | attr_path: None, | ||
111 | module_id, | 110 | module_id, |
112 | file_id: file_id.into(), | 111 | file_id: file_id.into(), |
113 | raw_items: &raw_items, | 112 | raw_items: &raw_items, |
114 | parent_module: None, | 113 | mod_dir: ModDir::root(), |
115 | } | 114 | } |
116 | .collect(raw_items.items()); | 115 | .collect(raw_items.items()); |
117 | 116 | ||
@@ -481,13 +480,13 @@ where | |||
481 | if !self.macro_stack_monitor.is_poison(macro_def_id) { | 480 | if !self.macro_stack_monitor.is_poison(macro_def_id) { |
482 | let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items); | 481 | let file_id: HirFileId = macro_call_id.as_file(MacroFileKind::Items); |
483 | let raw_items = self.db.raw_items(file_id); | 482 | let raw_items = self.db.raw_items(file_id); |
483 | let mod_dir = self.mod_dirs[&module_id].clone(); | ||
484 | ModCollector { | 484 | ModCollector { |
485 | def_collector: &mut *self, | 485 | def_collector: &mut *self, |
486 | file_id, | 486 | file_id, |
487 | attr_path: None, | ||
488 | module_id, | 487 | module_id, |
489 | raw_items: &raw_items, | 488 | raw_items: &raw_items, |
490 | parent_module: None, | 489 | mod_dir, |
491 | } | 490 | } |
492 | .collect(raw_items.items()); | 491 | .collect(raw_items.items()); |
493 | } else { | 492 | } else { |
@@ -508,9 +507,8 @@ struct ModCollector<'a, D> { | |||
508 | def_collector: D, | 507 | def_collector: D, |
509 | module_id: CrateModuleId, | 508 | module_id: CrateModuleId, |
510 | file_id: HirFileId, | 509 | file_id: HirFileId, |
511 | attr_path: Option<&'a SmolStr>, | ||
512 | raw_items: &'a raw::RawItems, | 510 | raw_items: &'a raw::RawItems, |
513 | parent_module: Option<ParentModule<'a>>, | 511 | mod_dir: ModDir, |
514 | } | 512 | } |
515 | 513 | ||
516 | impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> | 514 | impl<DB> ModCollector<'_, &'_ mut DefCollector<'_, DB>> |
@@ -518,6 +516,10 @@ where | |||
518 | DB: DefDatabase, | 516 | DB: DefDatabase, |
519 | { | 517 | { |
520 | fn collect(&mut self, items: &[raw::RawItem]) { | 518 | fn collect(&mut self, items: &[raw::RawItem]) { |
519 | // Note: don't assert that inserted value is fresh: it's simply not true | ||
520 | // for macros. | ||
521 | self.def_collector.mod_dirs.insert(self.module_id, self.mod_dir.clone()); | ||
522 | |||
521 | // Prelude module is always considered to be `#[macro_use]`. | 523 | // Prelude module is always considered to be `#[macro_use]`. |
522 | if let Some(prelude_module) = self.def_collector.def_map.prelude { | 524 | if let Some(prelude_module) = self.def_collector.def_map.prelude { |
523 | if prelude_module.krate != self.def_collector.def_map.krate { | 525 | if prelude_module.krate != self.def_collector.def_map.krate { |
@@ -561,15 +563,13 @@ where | |||
561 | raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => { | 563 | raw::ModuleData::Definition { name, items, ast_id, attr_path, is_macro_use } => { |
562 | let module_id = | 564 | let module_id = |
563 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); | 565 | 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 | 566 | ||
566 | ModCollector { | 567 | ModCollector { |
567 | def_collector: &mut *self.def_collector, | 568 | def_collector: &mut *self.def_collector, |
568 | module_id, | 569 | module_id, |
569 | attr_path: attr_path.as_ref(), | ||
570 | file_id: self.file_id, | 570 | file_id: self.file_id, |
571 | raw_items: self.raw_items, | 571 | raw_items: self.raw_items, |
572 | parent_module: Some(parent_module), | 572 | mod_dir: self.mod_dir.descend_into_definition(name, attr_path.as_ref()), |
573 | } | 573 | } |
574 | .collect(&*items); | 574 | .collect(&*items); |
575 | if *is_macro_use { | 575 | if *is_macro_use { |
@@ -579,26 +579,21 @@ where | |||
579 | // out of line module, resolve, parse and recurse | 579 | // out of line module, resolve, parse and recurse |
580 | raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => { | 580 | raw::ModuleData::Declaration { name, ast_id, attr_path, is_macro_use } => { |
581 | let ast_id = ast_id.with_file_id(self.file_id); | 581 | 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(); | 582 | match self.mod_dir.resolve_submodule( |
583 | match resolve_submodule( | ||
584 | self.def_collector.db, | 583 | self.def_collector.db, |
585 | self.file_id, | 584 | self.file_id, |
586 | self.attr_path, | ||
587 | name, | 585 | name, |
588 | is_root, | ||
589 | attr_path.as_ref(), | 586 | attr_path.as_ref(), |
590 | self.parent_module, | ||
591 | ) { | 587 | ) { |
592 | Ok(file_id) => { | 588 | Ok((file_id, mod_dir)) => { |
593 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); | 589 | 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()); | 590 | let raw_items = self.def_collector.db.raw_items(file_id.into()); |
595 | ModCollector { | 591 | ModCollector { |
596 | def_collector: &mut *self.def_collector, | 592 | def_collector: &mut *self.def_collector, |
597 | module_id, | 593 | module_id, |
598 | attr_path: attr_path.as_ref(), | ||
599 | file_id: file_id.into(), | 594 | file_id: file_id.into(), |
600 | raw_items: &raw_items, | 595 | raw_items: &raw_items, |
601 | parent_module: None, | 596 | mod_dir, |
602 | } | 597 | } |
603 | .collect(raw_items.items()); | 598 | .collect(raw_items.items()); |
604 | if *is_macro_use { | 599 | if *is_macro_use { |
@@ -747,6 +742,7 @@ mod tests { | |||
747 | glob_imports: FxHashMap::default(), | 742 | glob_imports: FxHashMap::default(), |
748 | unresolved_imports: Vec::new(), | 743 | unresolved_imports: Vec::new(), |
749 | unexpanded_macros: Vec::new(), | 744 | unexpanded_macros: Vec::new(), |
745 | mod_dirs: FxHashMap::default(), | ||
750 | macro_stack_monitor: monitor, | 746 | macro_stack_monitor: monitor, |
751 | cfg_options: &CfgOptions::default(), | 747 | cfg_options: &CfgOptions::default(), |
752 | }; | 748 | }; |