diff options
Diffstat (limited to 'crates/ra_hir_def/src/adt.rs')
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 43 |
1 files changed, 32 insertions, 11 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index c9f30923e..3666529b0 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -12,25 +12,25 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner}; | |||
12 | 12 | ||
13 | use crate::{ | 13 | use crate::{ |
14 | db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, | 14 | db::DefDatabase, trace::Trace, type_ref::TypeRef, AstItemDef, EnumId, HasChildSource, |
15 | LocalEnumVariantId, LocalStructFieldId, StructOrUnionId, VariantId, | 15 | LocalEnumVariantId, LocalStructFieldId, StructId, UnionId, VariantId, |
16 | }; | 16 | }; |
17 | 17 | ||
18 | /// Note that we use `StructData` for unions as well! | 18 | /// Note that we use `StructData` for unions as well! |
19 | #[derive(Debug, Clone, PartialEq, Eq)] | 19 | #[derive(Debug, Clone, PartialEq, Eq)] |
20 | pub struct StructData { | 20 | pub struct StructData { |
21 | pub name: Option<Name>, | 21 | pub name: Name, |
22 | pub variant_data: Arc<VariantData>, | 22 | pub variant_data: Arc<VariantData>, |
23 | } | 23 | } |
24 | 24 | ||
25 | #[derive(Debug, Clone, PartialEq, Eq)] | 25 | #[derive(Debug, Clone, PartialEq, Eq)] |
26 | pub struct EnumData { | 26 | pub struct EnumData { |
27 | pub name: Option<Name>, | 27 | pub name: Name, |
28 | pub variants: Arena<LocalEnumVariantId, EnumVariantData>, | 28 | pub variants: Arena<LocalEnumVariantId, EnumVariantData>, |
29 | } | 29 | } |
30 | 30 | ||
31 | #[derive(Debug, Clone, PartialEq, Eq)] | 31 | #[derive(Debug, Clone, PartialEq, Eq)] |
32 | pub struct EnumVariantData { | 32 | pub struct EnumVariantData { |
33 | pub name: Option<Name>, | 33 | pub name: Name, |
34 | pub variant_data: Arc<VariantData>, | 34 | pub variant_data: Arc<VariantData>, |
35 | } | 35 | } |
36 | 36 | ||
@@ -49,26 +49,38 @@ pub struct StructFieldData { | |||
49 | } | 49 | } |
50 | 50 | ||
51 | impl StructData { | 51 | impl StructData { |
52 | pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructOrUnionId) -> Arc<StructData> { | 52 | pub(crate) fn struct_data_query(db: &impl DefDatabase, id: StructId) -> Arc<StructData> { |
53 | let src = id.source(db); | 53 | let src = id.source(db); |
54 | let name = src.value.name().map(|n| n.as_name()); | 54 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); |
55 | let variant_data = VariantData::new(src.value.kind()); | 55 | let variant_data = VariantData::new(src.value.kind()); |
56 | let variant_data = Arc::new(variant_data); | 56 | let variant_data = Arc::new(variant_data); |
57 | Arc::new(StructData { name, variant_data }) | 57 | Arc::new(StructData { name, variant_data }) |
58 | } | 58 | } |
59 | pub(crate) fn union_data_query(db: &impl DefDatabase, id: UnionId) -> Arc<StructData> { | ||
60 | let src = id.source(db); | ||
61 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | ||
62 | let variant_data = VariantData::new( | ||
63 | src.value | ||
64 | .record_field_def_list() | ||
65 | .map(ast::StructKind::Record) | ||
66 | .unwrap_or(ast::StructKind::Unit), | ||
67 | ); | ||
68 | let variant_data = Arc::new(variant_data); | ||
69 | Arc::new(StructData { name, variant_data }) | ||
70 | } | ||
59 | } | 71 | } |
60 | 72 | ||
61 | impl EnumData { | 73 | impl EnumData { |
62 | pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> { | 74 | pub(crate) fn enum_data_query(db: &impl DefDatabase, e: EnumId) -> Arc<EnumData> { |
63 | let src = e.source(db); | 75 | let src = e.source(db); |
64 | let name = src.value.name().map(|n| n.as_name()); | 76 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); |
65 | let mut trace = Trace::new_for_arena(); | 77 | let mut trace = Trace::new_for_arena(); |
66 | lower_enum(&mut trace, &src.value); | 78 | lower_enum(&mut trace, &src.value); |
67 | Arc::new(EnumData { name, variants: trace.into_arena() }) | 79 | Arc::new(EnumData { name, variants: trace.into_arena() }) |
68 | } | 80 | } |
69 | 81 | ||
70 | pub(crate) fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> { | 82 | pub fn variant(&self, name: &Name) -> Option<LocalEnumVariantId> { |
71 | let (id, _) = self.variants.iter().find(|(_id, data)| data.name.as_ref() == Some(name))?; | 83 | let (id, _) = self.variants.iter().find(|(_id, data)| &data.name == name)?; |
72 | Some(id) | 84 | Some(id) |
73 | } | 85 | } |
74 | } | 86 | } |
@@ -92,7 +104,7 @@ fn lower_enum( | |||
92 | trace.alloc( | 104 | trace.alloc( |
93 | || var.clone(), | 105 | || var.clone(), |
94 | || EnumVariantData { | 106 | || EnumVariantData { |
95 | name: var.name().map(|it| it.as_name()), | 107 | name: var.name().map_or_else(Name::missing, |it| it.as_name()), |
96 | variant_data: Arc::new(VariantData::new(var.kind())), | 108 | variant_data: Arc::new(VariantData::new(var.kind())), |
97 | }, | 109 | }, |
98 | ); | 110 | ); |
@@ -117,6 +129,10 @@ impl VariantData { | |||
117 | } | 129 | } |
118 | } | 130 | } |
119 | 131 | ||
132 | pub fn field(&self, name: &Name) -> Option<LocalStructFieldId> { | ||
133 | self.fields().iter().find_map(|(id, data)| if &data.name == name { Some(id) } else { None }) | ||
134 | } | ||
135 | |||
120 | pub fn is_unit(&self) -> bool { | 136 | pub fn is_unit(&self) -> bool { |
121 | match self { | 137 | match self { |
122 | VariantData::Unit => true, | 138 | VariantData::Unit => true, |
@@ -137,7 +153,12 @@ impl HasChildSource for VariantId { | |||
137 | let src = it.parent.child_source(db); | 153 | let src = it.parent.child_source(db); |
138 | src.map(|map| map[it.local_id].kind()) | 154 | src.map(|map| map[it.local_id].kind()) |
139 | } | 155 | } |
140 | VariantId::StructId(it) => it.0.source(db).map(|it| it.kind()), | 156 | VariantId::StructId(it) => it.source(db).map(|it| it.kind()), |
157 | VariantId::UnionId(it) => it.source(db).map(|it| { | ||
158 | it.record_field_def_list() | ||
159 | .map(ast::StructKind::Record) | ||
160 | .unwrap_or(ast::StructKind::Unit) | ||
161 | }), | ||
141 | }; | 162 | }; |
142 | let mut trace = Trace::new_for_map(); | 163 | let mut trace = Trace::new_for_map(); |
143 | lower_struct(&mut trace, &src.value); | 164 | lower_struct(&mut trace, &src.value); |