diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 70 |
1 files changed, 34 insertions, 36 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index c5b73cfbe..8830b4624 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -6,14 +6,17 @@ use ra_db::FileId; | |||
6 | 6 | ||
7 | use crate::{ | 7 | use crate::{ |
8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, | 8 | Function, Module, Struct, Enum, Const, Static, Trait, TypeAlias, |
9 | DefDatabase, HirFileId, Name, Path, Problem, Crate, | 9 | DefDatabase, HirFileId, Name, Path, Crate, |
10 | KnownName, | 10 | KnownName, |
11 | nameres::{Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, raw}, | 11 | nameres::{ |
12 | Resolution, PerNs, ModuleDef, ReachedFixedPoint, ResolveMode, | ||
13 | CrateDefMap, CrateModuleId, ModuleData, CrateMacroId, | ||
14 | diagnostics::DefDiagnostic, | ||
15 | raw, | ||
16 | }, | ||
12 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, | 17 | ids::{AstItemDef, LocationCtx, MacroCallLoc, SourceItemId, MacroCallId}, |
13 | }; | 18 | }; |
14 | 19 | ||
15 | use super::{CrateDefMap, CrateModuleId, ModuleData, CrateMacroId}; | ||
16 | |||
17 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { | 20 | pub(super) fn collect_defs(db: &impl DefDatabase, mut def_map: CrateDefMap) -> CrateDefMap { |
18 | // populate external prelude | 21 | // populate external prelude |
19 | for dep in def_map.krate.dependencies(db) { | 22 | for dep in def_map.krate.dependencies(db) { |
@@ -405,25 +408,27 @@ where | |||
405 | raw::ModuleData::Declaration { name, source_item_id } => { | 408 | raw::ModuleData::Declaration { name, source_item_id } => { |
406 | let source_item_id = source_item_id.with_file_id(self.file_id); | 409 | let source_item_id = source_item_id.with_file_id(self.file_id); |
407 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); | 410 | let is_root = self.def_collector.def_map.modules[self.module_id].parent.is_none(); |
408 | let (file_ids, problem) = | 411 | match resolve_submodule(self.def_collector.db, self.file_id, name, is_root) { |
409 | resolve_submodule(self.def_collector.db, self.file_id, name, is_root); | 412 | Ok(file_id) => { |
410 | 413 | let module_id = | |
411 | if let Some(problem) = problem { | 414 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); |
412 | self.def_collector.def_map.problems.add(source_item_id, problem) | 415 | let raw_items = self.def_collector.db.raw_items(file_id); |
413 | } | 416 | ModCollector { |
414 | 417 | def_collector: &mut *self.def_collector, | |
415 | if let Some(&file_id) = file_ids.first() { | 418 | module_id, |
416 | let module_id = | 419 | file_id: file_id.into(), |
417 | self.push_child_module(name.clone(), source_item_id, Some(file_id)); | 420 | raw_items: &raw_items, |
418 | let raw_items = self.def_collector.db.raw_items(file_id); | 421 | } |
419 | ModCollector { | 422 | .collect(raw_items.items()) |
420 | def_collector: &mut *self.def_collector, | ||
421 | module_id, | ||
422 | file_id: file_id.into(), | ||
423 | raw_items: &raw_items, | ||
424 | } | 423 | } |
425 | .collect(raw_items.items()) | 424 | Err(candidate) => self.def_collector.def_map.diagnostics.push( |
426 | } | 425 | DefDiagnostic::UnresolvedModule { |
426 | module: self.module_id, | ||
427 | declaration: source_item_id, | ||
428 | candidate, | ||
429 | }, | ||
430 | ), | ||
431 | }; | ||
427 | } | 432 | } |
428 | } | 433 | } |
429 | } | 434 | } |
@@ -524,7 +529,7 @@ fn resolve_submodule( | |||
524 | file_id: HirFileId, | 529 | file_id: HirFileId, |
525 | name: &Name, | 530 | name: &Name, |
526 | is_root: bool, | 531 | is_root: bool, |
527 | ) -> (Vec<FileId>, Option<Problem>) { | 532 | ) -> Result<FileId, RelativePathBuf> { |
528 | // FIXME: handle submodules of inline modules properly | 533 | // FIXME: handle submodules of inline modules properly |
529 | let file_id = file_id.original_file(db); | 534 | let file_id = file_id.original_file(db); |
530 | let source_root_id = db.file_source_root(file_id); | 535 | let source_root_id = db.file_source_root(file_id); |
@@ -545,17 +550,10 @@ fn resolve_submodule( | |||
545 | candidates.push(file_dir_mod.clone()); | 550 | candidates.push(file_dir_mod.clone()); |
546 | }; | 551 | }; |
547 | let sr = db.source_root(source_root_id); | 552 | let sr = db.source_root(source_root_id); |
548 | let points_to = candidates | 553 | let mut points_to = candidates.into_iter().filter_map(|path| sr.files.get(&path)).map(|&it| it); |
549 | .into_iter() | 554 | // FIXME: handle ambiguity |
550 | .filter_map(|path| sr.files.get(&path)) | 555 | match points_to.next() { |
551 | .map(|&it| it) | 556 | Some(file_id) => Ok(file_id), |
552 | .collect::<Vec<_>>(); | 557 | None => Err(if is_dir_owner { file_mod } else { file_dir_mod }), |
553 | let problem = if points_to.is_empty() { | 558 | } |
554 | Some(Problem::UnresolvedModule { | ||
555 | candidate: if is_dir_owner { file_mod } else { file_dir_mod }, | ||
556 | }) | ||
557 | } else { | ||
558 | None | ||
559 | }; | ||
560 | (points_to, problem) | ||
561 | } | 559 | } |