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.rs69
1 files changed, 30 insertions, 39 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs
index 4fb298155..39cadc94a 100644
--- a/crates/ra_hir/src/nameres/collector.rs
+++ b/crates/ra_hir/src/nameres/collector.rs
@@ -3,10 +3,11 @@ use rustc_hash::FxHashMap;
3use relative_path::RelativePathBuf; 3use relative_path::RelativePathBuf;
4use test_utils::tested_by; 4use test_utils::tested_by;
5use ra_db::FileId; 5use ra_db::FileId;
6use ra_syntax::ast;
6 7
7use crate::{ 8use crate::{
8 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, 9 Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias,
9 DefDatabase, HirFileId, Name, Path, SourceItemId, 10 DefDatabase, HirFileId, Name, Path,
10 KnownName, 11 KnownName,
11 nameres::{ 12 nameres::{
12 Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, 13 Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode,
@@ -15,6 +16,7 @@ use crate::{
15 raw, 16 raw,
16 }, 17 },
17 ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId}, 18 ids::{AstItemDef, LocationCtx, MacroCallLoc, MacroCallId, MacroDefId},
19 AstId,
18}; 20};
19 21
20pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { 22pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap {
@@ -51,7 +53,7 @@ struct DefCollector<DB> {
51 def_map: CrateDefMap, 53 def_map: CrateDefMap,
52 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>, 54 glob_imports: FxHashMap<CrateModuleId, Vec<(CrateModuleId, raw::ImportId)>>,
53 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>, 55 unresolved_imports: Vec<(CrateModuleId, raw::ImportId, raw::ImportData)>,
54 unexpanded_macros: Vec<(CrateModuleId, SourceItemId, Path)>, 56 unexpanded_macros: Vec<(CrateModuleId, AstId<ast::MacroCall>, Path)>,
55 global_macro_scope: FxHashMap<Name, MacroDefId>, 57 global_macro_scope: FxHashMap<Name, MacroDefId>,
56} 58}
57 59
@@ -293,7 +295,7 @@ where
293 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new()); 295 let mut macros = std::mem::replace(&mut self.unexpanded_macros, Vec::new());
294 let mut resolved = Vec::new(); 296 let mut resolved = Vec::new();
295 let mut res = ReachedFixedPoint::Yes; 297 let mut res = ReachedFixedPoint::Yes;
296 macros.retain(|(module_id, source_item_id, path)| { 298 macros.retain(|(module_id, ast_id, path)| {
297 if path.segments.len() != 2 { 299 if path.segments.len() != 2 {
298 return true; 300 return true;
299 } 301 }
@@ -309,8 +311,7 @@ where
309 res = ReachedFixedPoint::No; 311 res = ReachedFixedPoint::No;
310 let def_map = self.db.crate_def_map(krate); 312 let def_map = self.db.crate_def_map(krate);
311 if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() { 313 if let Some(macro_id) = def_map.public_macros.get(&path.segments[1].name).cloned() {
312 let call_id = 314 let call_id = MacroCallLoc { def: macro_id, ast_id: *ast_id }.id(self.db);
313 MacroCallLoc { def: macro_id, source_item_id: *source_item_id }.id(self.db);
314 resolved.push((*module_id, call_id)); 315 resolved.push((*module_id, call_id));
315 } 316 }
316 false 317 false
@@ -364,12 +365,9 @@ where
364 fn collect_module(&mut self, module: &raw::ModuleData) { 365 fn collect_module(&mut self, module: &raw::ModuleData) {
365 match module { 366 match module {
366 // inline module, just recurse 367 // inline module, just recurse
367 raw::ModuleData::Definition { name, items, source_item_id } => { 368 raw::ModuleData::Definition { name, items, ast_id } => {
368 let module_id = self.push_child_module( 369 let module_id =
369 name.clone(), 370 self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None);
370 source_item_id.with_file_id(self.file_id),
371 None,
372 );
373 ModCollector { 371 ModCollector {
374 def_collector: &mut *self.def_collector, 372 def_collector: &mut *self.def_collector,
375 module_id, 373 module_id,
@@ -379,13 +377,12 @@ where
379 .collect(&*items); 377 .collect(&*items);
380 } 378 }
381 // out of line module, resovle, parse and recurse 379 // out of line module, resovle, parse and recurse
382 raw::ModuleData::Declaration { name, source_item_id } => { 380 raw::ModuleData::Declaration { name, ast_id } => {
383 let source_item_id = source_item_id.with_file_id(self.file_id); 381 let ast_id = ast_id.with_file_id(self.file_id);
384 let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); 382 let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none();
385 match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { 383 match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) {
386 Ok(file_id) => { 384 Ok(file_id) => {
387 let module_id = 385 let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id));
388 self.push_child_module(name.clone(), source_item_id, Some(file_id));
389 let raw_items = self.def_collector.db.raw_items(file_id.into()); 386 let raw_items = self.def_collector.db.raw_items(file_id.into());
390 ModCollector { 387 ModCollector {
391 def_collector: &mut *self.def_collector, 388 def_collector: &mut *self.def_collector,
@@ -398,7 +395,7 @@ where
398 Err(candidate) => self.def_collector.def_map.diagnostics.push( 395 Err(candidate) => self.def_collector.def_map.diagnostics.push(
399 DefDiagnostic::UnresolvedModule { 396 DefDiagnostic::UnresolvedModule {
400 module: self.module_id, 397 module: self.module_id,
401 declaration: source_item_id, 398 declaration: ast_id,
402 candidate, 399 candidate,
403 }, 400 },
404 ), 401 ),
@@ -410,7 +407,7 @@ where
410 fn push_child_module( 407 fn push_child_module(
411 &mut self, 408 &mut self,
412 name: Name, 409 name: Name,
413 declaration: SourceItemId, 410 declaration: AstId<ast::Module>,
414 definition: Option<FileId>, 411 definition: Option<FileId>,
415 ) -> CrateModuleId { 412 ) -> CrateModuleId {
416 let modules = &mut self.def_collector.def_map.modules; 413 let modules = &mut self.def_collector.def_map.modules;
@@ -432,23 +429,24 @@ where
432 fn define_def(&mut self, def: &raw::DefData) { 429 fn define_def(&mut self, def: &raw::DefData) {
433 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id }; 430 let module = Module { krate: self.def_collector.def_map.krate, module_id: self.module_id };
434 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into()); 431 let ctx = LocationCtx::new(self.def_collector.db, module, self.file_id.into());
435 macro_rules! id { 432
436 () => { 433 macro_rules! def {
437 AstItemDef::from_source_item_id_unchecked(ctx, def.source_item_id) 434 ($kind:ident, $ast_id:ident) => {
435 $kind { id: AstItemDef::from_ast_id(ctx, $ast_id) }.into()
438 }; 436 };
439 } 437 }
440 let name = def.name.clone(); 438 let name = def.name.clone();
441 let def: PerNs<ModuleDef> = match def.kind { 439 let def: PerNs<ModuleDef> = match def.kind {
442 raw::DefKind::Function => PerNs::values(Function { id: id!() }.into()), 440 raw::DefKind::Function(ast_id) => PerNs::values(def!(Function, ast_id)),
443 raw::DefKind::Struct => { 441 raw::DefKind::Struct(ast_id) => {
444 let s = Struct { id: id!() }.into(); 442 let s = def!(Struct, ast_id);
445 PerNs::both(s, s) 443 PerNs::both(s, s)
446 } 444 }
447 raw::DefKind::Enum => PerNs::types(Enum { id: id!() }.into()), 445 raw::DefKind::Enum(ast_id) => PerNs::types(def!(Enum, ast_id)),
448 raw::DefKind::Const => PerNs::values(Const { id: id!() }.into()), 446 raw::DefKind::Const(ast_id) => PerNs::values(def!(Const, ast_id)),
449 raw::DefKind::Static => PerNs::values(Static { id: id!() }.into()), 447 raw::DefKind::Static(ast_id) => PerNs::values(def!(Static, ast_id)),
450 raw::DefKind::Trait => PerNs::types(Trait { id: id!() }.into()), 448 raw::DefKind::Trait(ast_id) => PerNs::types(def!(Trait, ast_id)),
451 raw::DefKind::TypeAlias => PerNs::types(TypeAlias { id: id!() }.into()), 449 raw::DefKind::TypeAlias(ast_id) => PerNs::types(def!(TypeAlias, ast_id)),
452 }; 450 };
453 let resolution = Resolution { def, import: None }; 451 let resolution = Resolution { def, import: None };
454 self.def_collector.update(self.module_id, None, &[(name, resolution)]) 452 self.def_collector.update(self.module_id, None, &[(name, resolution)])
@@ -458,34 +456,27 @@ where
458 // Case 1: macro rules, define a macro in crate-global mutable scope 456 // Case 1: macro rules, define a macro in crate-global mutable scope
459 if is_macro_rules(&mac.path) { 457 if is_macro_rules(&mac.path) {
460 if let Some(name) = &mac.name { 458 if let Some(name) = &mac.name {
461 let macro_id = MacroDefId::MacroByExample { 459 let macro_id = MacroDefId(mac.ast_id.with_file_id(self.file_id));
462 source_item_id: mac.source_item_id.with_file_id(self.file_id),
463 };
464 self.def_collector.define_macro(name.clone(), macro_id, mac.export) 460 self.def_collector.define_macro(name.clone(), macro_id, mac.export)
465 } 461 }
466 return; 462 return;
467 } 463 }
468 464
469 let source_item_id = SourceItemId { file_id: self.file_id, item_id: mac.source_item_id }; 465 let ast_id = mac.ast_id.with_file_id(self.file_id);
470 466
471 // Case 2: try to expand macro_rules from this crate, triggering 467 // Case 2: try to expand macro_rules from this crate, triggering
472 // recursive item collection. 468 // recursive item collection.
473 if let Some(&macro_id) = 469 if let Some(&macro_id) =
474 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name)) 470 mac.path.as_ident().and_then(|name| self.def_collector.global_macro_scope.get(name))
475 { 471 {
476 let macro_call_id = 472 let macro_call_id = MacroCallLoc { def: macro_id, ast_id }.id(self.def_collector.db);
477 MacroCallLoc { def: macro_id, source_item_id }.id(self.def_collector.db);
478 473
479 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id); 474 self.def_collector.collect_macro_expansion(self.module_id, macro_call_id);
480 return; 475 return;
481 } 476 }
482 477
483 // Case 3: path to a macro from another crate, expand during name resolution 478 // Case 3: path to a macro from another crate, expand during name resolution
484 self.def_collector.unexpanded_macros.push(( 479 self.def_collector.unexpanded_macros.push((self.module_id, ast_id, mac.path.clone()))
485 self.module_id,
486 source_item_id,
487 mac.path.clone(),
488 ))
489 } 480 }
490} 481}
491 482