aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2019-04-14 10:15:11 +0100
committerFlorian Diebold <[email protected]>2019-04-14 10:28:53 +0100
commit4497e1d3eae0a72ee1e52be6ab547c67d31279c6 (patch)
tree88191878e2d35edd261829830012e5df003258ad
parent7650a44640a373e28f9eecc4623256ce6b9bbaa0 (diff)
Add Container enum to handle both kinds of container (impl/trait)
-rw-r--r--crates/ra_hir/src/code_model_api.rs51
-rw-r--r--crates/ra_hir/src/generics.rs20
-rw-r--r--crates/ra_hir/src/impl_block.rs2
-rw-r--r--crates/ra_hir/src/lib.rs2
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
793pub enum Container {
794 Trait(Trait),
795 ImplBlock(ImplBlock),
796}
797impl_froms!(Container: Trait, ImplBlock);
798
799impl 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
10use crate::{ 10use 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)]
31pub enum GenericDef { 32pub 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
113impl 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};