diff options
Diffstat (limited to 'crates/ra_hir/src/nameres/collector.rs')
-rw-r--r-- | crates/ra_hir/src/nameres/collector.rs | 67 |
1 files changed, 55 insertions, 12 deletions
diff --git a/crates/ra_hir/src/nameres/collector.rs b/crates/ra_hir/src/nameres/collector.rs index 06b732215..7da2dcdff 100644 --- a/crates/ra_hir/src/nameres/collector.rs +++ b/crates/ra_hir/src/nameres/collector.rs | |||
@@ -483,7 +483,7 @@ struct ModCollector<'a, D> { | |||
483 | module_id: CrateModuleId, | 483 | module_id: CrateModuleId, |
484 | file_id: HirFileId, | 484 | file_id: HirFileId, |
485 | raw_items: &'a raw::RawItems, | 485 | raw_items: &'a raw::RawItems, |
486 | parent_module: Option<&'a Name>, | 486 | parent_module: Option<ParentModule<'a>>, |
487 | } | 487 | } |
488 | 488 | ||
489 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> | 489 | impl<DB> ModCollector<'_, &'_ mut DefCollector<&'_ DB>> |
@@ -508,15 +508,16 @@ where | |||
508 | fn collect_module(&mut self, module: &raw::ModuleData) { | 508 | fn collect_module(&mut self, module: &raw::ModuleData) { |
509 | match module { | 509 | match module { |
510 | // inline module, just recurse | 510 | // inline module, just recurse |
511 | raw::ModuleData::Definition { name, items, ast_id } => { | 511 | raw::ModuleData::Definition { name, items, ast_id, attr_path } => { |
512 | let module_id = | 512 | let module_id = |
513 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); | 513 | self.push_child_module(name.clone(), ast_id.with_file_id(self.file_id), None); |
514 | let parent_module = ParentModule { name, attr_path: attr_path.as_ref() }; | ||
514 | ModCollector { | 515 | ModCollector { |
515 | def_collector: &mut *self.def_collector, | 516 | def_collector: &mut *self.def_collector, |
516 | module_id, | 517 | module_id, |
517 | file_id: self.file_id, | 518 | file_id: self.file_id, |
518 | raw_items: self.raw_items, | 519 | raw_items: self.raw_items, |
519 | parent_module: Some(name), | 520 | parent_module: Some(parent_module), |
520 | } | 521 | } |
521 | .collect(&*items); | 522 | .collect(&*items); |
522 | } | 523 | } |
@@ -530,7 +531,7 @@ where | |||
530 | name, | 531 | name, |
531 | is_root, | 532 | is_root, |
532 | attr_path.as_ref(), | 533 | attr_path.as_ref(), |
533 | self.parent_module, | 534 | self.parent_module.as_ref(), |
534 | ) { | 535 | ) { |
535 | Ok(file_id) => { | 536 | Ok(file_id) => { |
536 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); | 537 | let module_id = self.push_child_module(name.clone(), ast_id, Some(file_id)); |
@@ -647,7 +648,7 @@ fn resolve_submodule( | |||
647 | name: &Name, | 648 | name: &Name, |
648 | is_root: bool, | 649 | is_root: bool, |
649 | attr_path: Option<&SmolStr>, | 650 | attr_path: Option<&SmolStr>, |
650 | parent_module: Option<&Name>, | 651 | parent_module: Option<&ParentModule>, |
651 | ) -> Result<FileId, RelativePathBuf> { | 652 | ) -> Result<FileId, RelativePathBuf> { |
652 | let file_id = file_id.original_file(db); | 653 | let file_id = file_id.original_file(db); |
653 | let source_root_id = db.file_source_root(file_id); | 654 | let source_root_id = db.file_source_root(file_id); |
@@ -657,20 +658,49 @@ fn resolve_submodule( | |||
657 | let mod_name = path.file_stem().unwrap_or("unknown"); | 658 | let mod_name = path.file_stem().unwrap_or("unknown"); |
658 | 659 | ||
659 | let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) { | 660 | let resolve_mode = match (attr_path.filter(|p| !p.is_empty()), parent_module) { |
660 | (Some(file_path), Some(parent_name)) => { | 661 | (Some(file_path), Some(parent_module)) => { |
661 | let file_path = normalize_attribute_path(file_path); | 662 | let file_path = normalize_attribute_path(file_path); |
662 | let path = dir_path.join(format!("{}/{}", parent_name, file_path)).normalize(); | 663 | match parent_module.attribute_path() { |
663 | ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath(path)) | 664 | Some(parent_module_attr_path) => { |
665 | let path = dir_path | ||
666 | .join(format!( | ||
667 | "{}/{}", | ||
668 | normalize_attribute_path(parent_module_attr_path), | ||
669 | file_path | ||
670 | )) | ||
671 | .normalize(); | ||
672 | ResolutionMode::InlineModuleWithAttributePath( | ||
673 | InsideInlineModuleMode::WithAttributePath(path), | ||
674 | ) | ||
675 | } | ||
676 | None => { | ||
677 | let path = | ||
678 | dir_path.join(format!("{}/{}", parent_module.name, file_path)).normalize(); | ||
679 | ResolutionMode::InsideInlineModule(InsideInlineModuleMode::WithAttributePath( | ||
680 | path, | ||
681 | )) | ||
682 | } | ||
683 | } | ||
664 | } | 684 | } |
685 | (None, Some(parent_module)) => match parent_module.attribute_path() { | ||
686 | Some(parent_module_attr_path) => { | ||
687 | let path = dir_path.join(format!( | ||
688 | "{}/{}.rs", | ||
689 | normalize_attribute_path(parent_module_attr_path), | ||
690 | name | ||
691 | )); | ||
692 | ResolutionMode::InlineModuleWithAttributePath(InsideInlineModuleMode::File(path)) | ||
693 | } | ||
694 | None => { | ||
695 | let path = dir_path.join(format!("{}/{}.rs", parent_module.name, name)); | ||
696 | ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path)) | ||
697 | } | ||
698 | }, | ||
665 | (Some(file_path), None) => { | 699 | (Some(file_path), None) => { |
666 | let file_path = normalize_attribute_path(file_path); | 700 | let file_path = normalize_attribute_path(file_path); |
667 | let path = dir_path.join(file_path.as_ref()).normalize(); | 701 | let path = dir_path.join(file_path.as_ref()).normalize(); |
668 | ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path)) | 702 | ResolutionMode::OutOfLine(OutOfLineMode::WithAttributePath(path)) |
669 | } | 703 | } |
670 | (None, Some(parent_name)) => { | ||
671 | let path = dir_path.join(format!("{}/{}.rs", parent_name, name)); | ||
672 | ResolutionMode::InsideInlineModule(InsideInlineModuleMode::File(path)) | ||
673 | } | ||
674 | _ => { | 704 | _ => { |
675 | let is_dir_owner = is_root || mod_name == "mod"; | 705 | let is_dir_owner = is_root || mod_name == "mod"; |
676 | if is_dir_owner { | 706 | if is_dir_owner { |
@@ -743,6 +773,7 @@ impl InsideInlineModuleMode { | |||
743 | enum ResolutionMode { | 773 | enum ResolutionMode { |
744 | OutOfLine(OutOfLineMode), | 774 | OutOfLine(OutOfLineMode), |
745 | InsideInlineModule(InsideInlineModuleMode), | 775 | InsideInlineModule(InsideInlineModuleMode), |
776 | InlineModuleWithAttributePath(InsideInlineModuleMode), | ||
746 | } | 777 | } |
747 | 778 | ||
748 | impl ResolutionMode { | 779 | impl ResolutionMode { |
@@ -752,6 +783,7 @@ impl ResolutionMode { | |||
752 | match self { | 783 | match self { |
753 | OutOfLine(mode) => mode.resolve(source_root), | 784 | OutOfLine(mode) => mode.resolve(source_root), |
754 | InsideInlineModule(mode) => mode.resolve(source_root), | 785 | InsideInlineModule(mode) => mode.resolve(source_root), |
786 | InlineModuleWithAttributePath(mode) => mode.resolve(source_root), | ||
755 | } | 787 | } |
756 | } | 788 | } |
757 | } | 789 | } |
@@ -773,6 +805,17 @@ fn resolve_find_result( | |||
773 | } | 805 | } |
774 | } | 806 | } |
775 | 807 | ||
808 | struct ParentModule<'a> { | ||
809 | name: &'a Name, | ||
810 | attr_path: Option<&'a SmolStr>, | ||
811 | } | ||
812 | |||
813 | impl<'a> ParentModule<'a> { | ||
814 | pub fn attribute_path(&self) -> Option<&SmolStr> { | ||
815 | self.attr_path.filter(|p| !p.is_empty()) | ||
816 | } | ||
817 | } | ||
818 | |||
776 | #[cfg(test)] | 819 | #[cfg(test)] |
777 | mod tests { | 820 | mod tests { |
778 | use ra_db::SourceDatabase; | 821 | use ra_db::SourceDatabase; |