diff options
Diffstat (limited to 'crates/ra_hir/src/code_model_api.rs')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 51 |
1 files changed, 43 insertions, 8 deletions
diff --git a/crates/ra_hir/src/code_model_api.rs b/crates/ra_hir/src/code_model_api.rs index b53fe1f63..28de9e76a 100644 --- a/crates/ra_hir/src/code_model_api.rs +++ b/crates/ra_hir/src/code_model_api.rs | |||
@@ -189,7 +189,7 @@ impl Module { | |||
189 | } | 189 | } |
190 | } | 190 | } |
191 | 191 | ||
192 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 192 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
193 | let def_map = db.crate_def_map(self.krate); | 193 | let def_map = db.crate_def_map(self.krate); |
194 | Resolver::default().push_module_scope(def_map, self.module_id) | 194 | Resolver::default().push_module_scope(def_map, self.module_id) |
195 | } | 195 | } |
@@ -552,16 +552,21 @@ impl Function { | |||
552 | db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) | 552 | db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) |
553 | } | 553 | } |
554 | 554 | ||
555 | pub fn container(&self, db: &impl DefDatabase) -> Option<Container> { | ||
556 | if let Some(impl_block) = self.impl_block(db) { | ||
557 | Some(impl_block.into()) | ||
558 | } else if let Some(trait_) = self.parent_trait(db) { | ||
559 | Some(trait_.into()) | ||
560 | } else { | ||
561 | None | ||
562 | } | ||
563 | } | ||
564 | |||
555 | // FIXME: move to a more general type for 'body-having' items | 565 | // FIXME: move to a more general type for 'body-having' items |
556 | /// Builds a resolver for code inside this item. | 566 | /// Builds a resolver for code inside this item. |
557 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 567 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { |
558 | // take the outer scope... | 568 | // take the outer scope... |
559 | // FIXME abstract over containers (trait/impl) | 569 | let r = self.container(db).map_or_else(|| self.module(db).resolver(db), |c| c.resolver(db)); |
560 | let r = self | ||
561 | .impl_block(db) | ||
562 | .map(|ib| ib.resolver(db)) | ||
563 | .or_else(|| self.parent_trait(db).map(|tr| tr.resolver(db))) | ||
564 | .unwrap_or_else(|| self.module(db).resolver(db)); | ||
565 | // ...and add generic params, if present | 570 | // ...and add generic params, if present |
566 | let p = self.generic_params(db); | 571 | let p = self.generic_params(db); |
567 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; | 572 | let r = if !p.params.is_empty() { r.push_generic_params_scope(p) } else { r }; |
@@ -707,7 +712,7 @@ impl Trait { | |||
707 | db.trait_data(self) | 712 | db.trait_data(self) |
708 | } | 713 | } |
709 | 714 | ||
710 | pub fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 715 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
711 | let r = self.module(db).resolver(db); | 716 | let r = self.module(db).resolver(db); |
712 | // add generic params, if present | 717 | // add generic params, if present |
713 | let p = self.generic_params(db); | 718 | let p = self.generic_params(db); |
@@ -746,6 +751,21 @@ impl TypeAlias { | |||
746 | ImplBlock::containing(module_impls, (*self).into()) | 751 | ImplBlock::containing(module_impls, (*self).into()) |
747 | } | 752 | } |
748 | 753 | ||
754 | /// The containing trait, if this is a trait method definition. | ||
755 | pub fn parent_trait(&self, db: &impl DefDatabase) -> Option<Trait> { | ||
756 | db.trait_items_index(self.module(db)).get_parent_trait((*self).into()) | ||
757 | } | ||
758 | |||
759 | pub fn container(&self, db: &impl DefDatabase) -> Option<Container> { | ||
760 | if let Some(impl_block) = self.impl_block(db) { | ||
761 | Some(impl_block.into()) | ||
762 | } else if let Some(trait_) = self.parent_trait(db) { | ||
763 | Some(trait_.into()) | ||
764 | } else { | ||
765 | None | ||
766 | } | ||
767 | } | ||
768 | |||
749 | pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> { | 769 | pub fn type_ref(self, db: &impl DefDatabase) -> Arc<TypeRef> { |
750 | db.type_alias_ref(self) | 770 | db.type_alias_ref(self) |
751 | } | 771 | } |
@@ -769,3 +789,18 @@ impl Docs for TypeAlias { | |||
769 | docs_from_ast(&*self.source(db).1) | 789 | docs_from_ast(&*self.source(db).1) |
770 | } | 790 | } |
771 | } | 791 | } |
792 | |||
793 | pub enum Container { | ||
794 | Trait(Trait), | ||
795 | ImplBlock(ImplBlock), | ||
796 | } | ||
797 | impl_froms!(Container: Trait, ImplBlock); | ||
798 | |||
799 | impl Container { | ||
800 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { | ||
801 | match self { | ||
802 | Container::Trait(trait_) => trait_.resolver(db), | ||
803 | Container::ImplBlock(impl_block) => impl_block.resolver(db), | ||
804 | } | ||
805 | } | ||
806 | } | ||