aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/adt.rs')
-rw-r--r--crates/ra_hir_def/src/adt.rs43
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
13use crate::{ 13use 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)]
20pub struct StructData { 20pub 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)]
26pub struct EnumData { 26pub 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)]
32pub struct EnumVariantData { 32pub 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
51impl StructData { 51impl 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
61impl EnumData { 73impl 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);