aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/nameres/collector.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r--crates/ra_hir/src/nameres/collector.rs76
1 files changed, 45 insertions, 31 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index f2336c271..9992e054d 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -6,13 +6,13 @@ use ra_db::FileId;
6 6
7use crate::{ 7use crate::{
8 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, 8 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
9 PersistentHirDatabase, HirFileId, Name, Path, Problem, 9 PersistentHirDatabase, HirFileId, Name, Path, Problem, Crate,
10 KnownName, 10 KnownName,
11 nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, 11 nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw},
12 ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, 12 ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId},
13}; 13};
14 14
15use super::{CrateDefMap, CrateModuleId, ModuleData}; 15use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId};
16 16
17pub(super) fn collect_defs( 17pub(super) fn collect_defs(
18 db: &impl PersistentHirDatabase, 18 db: &impl PersistentHirDatabase,
@@ -52,7 +52,7 @@ struct DefCollector<DB> {
52 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, 52 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
53 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, 53 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
54 unexpanded_macros: Vec<(CrateModuleId, MacroCallId, Path, tt::Subtree)>, 54 unexpanded_macros: Vec<(CrateModuleId, MacroCallId, Path, tt::Subtree)>,
55 global_macro_scope: FxHashMap<Name, mbe::MacroRules>, 55 global_macro_scope: FxHashMap<Name, CrateMacroId>,
56} 56}
57 57
58impl<'a, DB> DefCollector<&'a DB> 58impl<'a, DB> DefCollector<&'a DB>
@@ -95,10 +95,11 @@ where
95 95
96 fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) { 96 fn define_macro(&mut self, name: Name, tt: &tt::Subtree, export: bool) {
97 if let Ok(rules) = mbe::MacroRules::parse(tt) { 97 if let Ok(rules) = mbe::MacroRules::parse(tt) {
98 let macro_id = self.def_map.macros.alloc(rules);
98 if export { 99 if export {
99 self.def_map.public_macros.insert(name.clone(), rules.clone()); 100 self.def_map.public_macros.insert(name.clone(), macro_id);
100 } 101 }
101 self.global_macro_scope.insert(name, rules); 102 self.global_macro_scope.insert(name, macro_id);
102 } 103 }
103 } 104 }
104 105
@@ -295,6 +296,7 @@ where
295 fn resolve_macros(&mut self) -> ReachedFixedPoint { 296 fn resolve_macros(&mut self) -> ReachedFixedPoint {
296 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); 297 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
297 let mut resolved = Vec::new(); 298 let mut resolved = Vec::new();
299 let mut res = ReachedFixedPoint::Yes;
298 macros.retain(|(module_id, call_id, path, tt)| { 300 macros.retain(|(module_id, call_id, path, tt)| {
299 if path.segments.len() != 2 { 301 if path.segments.len() != 2 {
300 return true; 302 return true;
@@ -308,19 +310,16 @@ where
308 Some(it) => it, 310 Some(it) => it,
309 _ => return true, 311 _ => return true,
310 }; 312 };
313 res = ReachedFixedPoint::No;
311 let def_map = self.db.crate_def_map(krate); 314 let def_map = self.db.crate_def_map(krate);
312 let rules = def_map.public_macros.get(&path.segments[1].name).cloned(); 315 if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() {
313 resolved.push((*module_id, *call_id, rules, tt.clone())); 316 resolved.push((*module_id, *call_id, (krate, macro_id), tt.clone()));
317 }
314 false 318 false
315 }); 319 });
316 let res = if resolved.is_empty() { ReachedFixedPoint::Yes } else { ReachedFixedPoint::No };
317 320
318 for (module_id, macro_call_id, rules, arg) in resolved { 321 for (module_id, macro_call_id, macro_def_id, arg) in resolved {
319 if let Some(rules) = rules { 322 self.collect_macro_expansion(module_id, macro_call_id, macro_def_id, arg);
320 if let Ok(tt) = rules.expand(&arg) {
321 self.collect_macro_expansion(module_id, macro_call_id, tt);
322 }
323 }
324 } 323 }
325 res 324 res
326 } 325 }
@@ -329,20 +328,32 @@ where
329 &mut self, 328 &mut self,
330 module_id: CrateModuleId, 329 module_id: CrateModuleId,
331 macro_call_id: MacroCallId, 330 macro_call_id: MacroCallId,
332 expansion: tt::Subtree, 331 macro_def_id: (Crate, CrateMacroId),
332 macro_arg: tt::Subtree,
333 ) { 333 ) {
334 // XXX: this **does not** go through a database, because we can't 334 let (macro_krate, macro_id) = macro_def_id;
335 // identify macro_call without adding the whole state of name resolution 335 let dm;
336 // as a parameter to the query. 336 let rules = if macro_krate == self.def_map.krate {
337 // 337 &self.def_map[macro_id]
338 // So, we run the queries "manually" and we must ensure that 338 } else {
339 // `db.hir_parse(macro_call_id)` returns the same source_file. 339 dm = self.db.crate_def_map(macro_krate);
340 let file_id: HirFileId = macro_call_id.into(); 340 &dm[macro_id]
341 let source_file = mbe::token_tree_to_ast_item_list(&expansion); 341 };
342 342 if let Ok(expansion) = rules.expand(&macro_arg) {
343 let raw_items = raw::RawItems::from_source_file(&source_file, file_id); 343 self.def_map.macro_resolutions.insert(macro_call_id, macro_def_id);
344 ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items } 344 // XXX: this **does not** go through a database, because we can't
345 .collect(raw_items.items()) 345 // identify macro_call without adding the whole state of name resolution
346 // as a parameter to the query.
347 //
348 // So, we run the queries "manually" and we must ensure that
349 // `db.hir_parse(macro_call_id)` returns the same source_file.
350 let file_id: HirFileId = macro_call_id.into();
351 let source_file = mbe::token_tree_to_ast_item_list(&expansion);
352
353 let raw_items = raw::RawItems::from_source_file(&source_file, file_id);
354 ModCollector { def_collector: &mut *self, file_id, module_id, raw_items: &raw_items }
355 .collect(raw_items.items())
356 }
346 } 357 }
347 358
348 fn finish(self) -> CrateDefMap { 359 fn finish(self) -> CrateDefMap {
@@ -486,12 +497,15 @@ where
486 497
487 // Case 2: try to expand macro_rules from this crate, triggering 498 // Case 2: try to expand macro_rules from this crate, triggering
488 // recursive item collection. 499 // recursive item collection.
489 if let Some(rules) = 500 if let Some(&macro_id) =
490 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) 501 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name))
491 { 502 {
492 if let Ok(tt) = rules.expand(&mac.arg) { 503 self.def_collector.collect_macro_expansion(
493 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id, tt); 504 self.module_id,
494 } 505 macro_call_id,
506 (self.def_collector.def_map.krate, macro_id),
507 mac.arg.clone(),
508 );
495 return; 509 return;
496 } 510 }
497 511