diff options
author | Florian Diebold <[email protected]> | 2019-04-14 10:15:11 +0100 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2019-04-14 10:28:53 +0100 |
commit | 4497e1d3eae0a72ee1e52be6ab547c67d31279c6 (patch) | |
tree | 88191878e2d35edd261829830012e5df003258ad /crates/ra_hir | |
parent | 7650a44640a373e28f9eecc4623256ce6b9bbaa0 (diff) |
Add Container enum to handle both kinds of container (impl/trait)
Diffstat (limited to 'crates/ra_hir')
-rw-r--r-- | crates/ra_hir/src/code_model_api.rs | 51 | ||||
-rw-r--r-- | crates/ra_hir/src/generics.rs | 20 | ||||
-rw-r--r-- | crates/ra_hir/src/impl_block.rs | 2 | ||||
-rw-r--r-- | crates/ra_hir/src/lib.rs | 2 |
4 files changed, 58 insertions, 17 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 | } | ||
diff --git a/crates/ra_hir/src/generics.rs b/crates/ra_hir/src/generics.rs index 51c846e91..f92b146ef 100644 --- a/crates/ra_hir/src/generics.rs +++ b/crates/ra_hir/src/generics.rs | |||
@@ -9,7 +9,7 @@ use ra_syntax::ast::{self, NameOwner, TypeParamsOwner}; | |||
9 | 9 | ||
10 | use crate::{ | 10 | use crate::{ |
11 | db::DefDatabase, | 11 | db::DefDatabase, |
12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock | 12 | Name, AsName, Function, Struct, Enum, Trait, TypeAlias, ImplBlock, Container |
13 | }; | 13 | }; |
14 | 14 | ||
15 | /// Data about a generic parameter (to a function, struct, impl, ...). | 15 | /// Data about a generic parameter (to a function, struct, impl, ...). |
@@ -27,6 +27,7 @@ pub struct GenericParams { | |||
27 | pub(crate) params: Vec<GenericParam>, | 27 | pub(crate) params: Vec<GenericParam>, |
28 | } | 28 | } |
29 | 29 | ||
30 | // FIXME: consts can have type parameters from their parents (i.e. associated consts of traits) | ||
30 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] | 31 | #[derive(Clone, Copy, PartialEq, Eq, Debug, Hash)] |
31 | pub enum GenericDef { | 32 | pub enum GenericDef { |
32 | Function(Function), | 33 | Function(Function), |
@@ -45,12 +46,8 @@ impl GenericParams { | |||
45 | ) -> Arc<GenericParams> { | 46 | ) -> Arc<GenericParams> { |
46 | let mut generics = GenericParams::default(); | 47 | let mut generics = GenericParams::default(); |
47 | let parent = match def { | 48 | let parent = match def { |
48 | // FIXME abstract over containers (trait/impl) | 49 | GenericDef::Function(it) => it.container(db).map(GenericDef::from), |
49 | GenericDef::Function(it) => it | 50 | GenericDef::TypeAlias(it) => it.container(db).map(GenericDef::from), |
50 | .impl_block(db) | ||
51 | .map(GenericDef::from) | ||
52 | .or_else(|| it.parent_trait(db).map(GenericDef::from)), | ||
53 | GenericDef::TypeAlias(it) => it.impl_block(db).map(GenericDef::from), | ||
54 | GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None, | 51 | GenericDef::Struct(_) | GenericDef::Enum(_) | GenericDef::Trait(_) => None, |
55 | GenericDef::ImplBlock(_) => None, | 52 | GenericDef::ImplBlock(_) => None, |
56 | }; | 53 | }; |
@@ -112,3 +109,12 @@ impl GenericParams { | |||
112 | vec | 109 | vec |
113 | } | 110 | } |
114 | } | 111 | } |
112 | |||
113 | impl From<Container> for GenericDef { | ||
114 | fn from(c: Container) -> Self { | ||
115 | match c { | ||
116 | Container::Trait(trait_) => trait_.into(), | ||
117 | Container::ImplBlock(impl_block) => impl_block.into(), | ||
118 | } | ||
119 | } | ||
120 | } | ||
diff --git a/crates/ra_hir/src/impl_block.rs b/crates/ra_hir/src/impl_block.rs index 42c02c9fb..71486aa2d 100644 --- a/crates/ra_hir/src/impl_block.rs +++ b/crates/ra_hir/src/impl_block.rs | |||
@@ -96,7 +96,7 @@ impl ImplBlock { | |||
96 | db.generic_params((*self).into()) | 96 | db.generic_params((*self).into()) |
97 | } | 97 | } |
98 | 98 | ||
99 | pub(crate) fn resolver(&self, db: &impl HirDatabase) -> Resolver { | 99 | pub(crate) fn resolver(&self, db: &impl DefDatabase) -> Resolver { |
100 | let r = self.module().resolver(db); | 100 | let r = self.module().resolver(db); |
101 | // add generic params, if present | 101 | // add generic params, if present |
102 | let p = self.generic_params(db); | 102 | let p = self.generic_params(db); |
diff --git a/crates/ra_hir/src/lib.rs b/crates/ra_hir/src/lib.rs index c284d1693..24e08f8cc 100644 --- a/crates/ra_hir/src/lib.rs +++ b/crates/ra_hir/src/lib.rs | |||
@@ -78,5 +78,5 @@ pub use self::code_model_api::{ | |||
78 | Function, FnSignature, | 78 | Function, FnSignature, |
79 | StructField, FieldSource, | 79 | StructField, FieldSource, |
80 | Static, Const, ConstSignature, | 80 | Static, Const, ConstSignature, |
81 | Trait, TypeAlias, | 81 | Trait, TypeAlias, Container, |
82 | }; | 82 | }; |