aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r--crates/ra_hir/src/adt.rs176
1 files changed, 4 insertions, 172 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs
index 4fa2062bd..0436d20b7 100644
--- a/crates/ra_hir/src/adt.rs
+++ b/crates/ra_hir/src/adt.rs
@@ -3,152 +3,16 @@
3 3
4use std::sync::Arc; 4use std::sync::Arc;
5 5
6use hir_def::{type_ref::TypeRef, LocalEnumVariantId}; 6use hir_def::adt::VariantData;
7use hir_expand::name::AsName;
8use ra_arena::{impl_arena_id, Arena, RawId};
9use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner};
10 7
11use crate::{ 8use crate::{
12 db::{AstDatabase, DefDatabase, HirDatabase}, 9 db::{DefDatabase, HirDatabase},
13 Enum, EnumVariant, FieldSource, HasSource, Module, Name, Source, Struct, StructField, 10 EnumVariant, Module, Name, Struct, StructField,
14}; 11};
15 12
16impl Struct { 13impl Struct {
17 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> { 14 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
18 db.struct_data(self).variant_data.clone() 15 db.struct_data(self.id).variant_data.clone()
19 }
20}
21
22/// Note that we use `StructData` for unions as well!
23#[derive(Debug, Clone, PartialEq, Eq)]
24pub struct StructData {
25 pub(crate) name: Option<Name>,
26 pub(crate) variant_data: Arc<VariantData>,
27}
28
29impl StructData {
30 fn new(struct_def: &ast::StructDef) -> StructData {
31 let name = struct_def.name().map(|n| n.as_name());
32 let variant_data = VariantData::new(struct_def.kind());
33 let variant_data = Arc::new(variant_data);
34 StructData { name, variant_data }
35 }
36
37 pub(crate) fn struct_data_query(
38 db: &(impl DefDatabase + AstDatabase),
39 struct_: Struct,
40 ) -> Arc<StructData> {
41 let src = struct_.source(db);
42 Arc::new(StructData::new(&src.ast))
43 }
44}
45
46fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = ast::EnumVariant> {
47 enum_def.variant_list().into_iter().flat_map(|it| it.variants())
48}
49
50impl EnumVariant {
51 pub(crate) fn source_impl(
52 self,
53 db: &(impl DefDatabase + AstDatabase),
54 ) -> Source<ast::EnumVariant> {
55 let src = self.parent.source(db);
56 let ast = variants(&src.ast)
57 .zip(db.enum_data(self.parent).variants.iter())
58 .find(|(_syntax, (id, _))| *id == self.id)
59 .unwrap()
60 .0;
61 Source { file_id: src.file_id, ast }
62 }
63 pub(crate) fn variant_data(self, db: &impl DefDatabase) -> Arc<VariantData> {
64 db.enum_data(self.parent).variants[self.id].variant_data.clone()
65 }
66}
67
68#[derive(Debug, Clone, PartialEq, Eq)]
69pub struct EnumData {
70 pub(crate) name: Option<Name>,
71 pub(crate) variants: Arena<LocalEnumVariantId, EnumVariantData>,
72}
73
74impl EnumData {
75 pub(crate) fn enum_data_query(db: &(impl DefDatabase + AstDatabase), e: Enum) -> Arc<EnumData> {
76 let src = e.source(db);
77 let name = src.ast.name().map(|n| n.as_name());
78 let variants = variants(&src.ast)
79 .map(|var| EnumVariantData {
80 name: var.name().map(|it| it.as_name()),
81 variant_data: Arc::new(VariantData::new(var.kind())),
82 })
83 .collect();
84 Arc::new(EnumData { name, variants })
85 }
86}
87
88#[derive(Debug, Clone, PartialEq, Eq)]
89pub(crate) struct EnumVariantData {
90 pub(crate) name: Option<Name>,
91 variant_data: Arc<VariantData>,
92}
93
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
95pub(crate) struct StructFieldId(RawId);
96impl_arena_id!(StructFieldId);
97
98/// A single field of an enum variant or struct
99#[derive(Debug, Clone, PartialEq, Eq)]
100pub struct StructFieldData {
101 pub(crate) name: Name,
102 pub(crate) type_ref: TypeRef,
103}
104
105/// Fields of an enum variant or struct
106#[derive(Debug, Clone, PartialEq, Eq)]
107pub(crate) struct VariantData(VariantDataInner);
108
109#[derive(Debug, Clone, PartialEq, Eq)]
110enum VariantDataInner {
111 Struct(Arena<StructFieldId, StructFieldData>),
112 Tuple(Arena<StructFieldId, StructFieldData>),
113 Unit,
114}
115
116impl VariantData {
117 pub(crate) fn fields(&self) -> Option<&Arena<StructFieldId, StructFieldData>> {
118 match &self.0 {
119 VariantDataInner::Struct(fields) | VariantDataInner::Tuple(fields) => Some(fields),
120 _ => None,
121 }
122 }
123}
124
125impl VariantData {
126 fn new(flavor: StructKind) -> Self {
127 let inner = match flavor {
128 ast::StructKind::Tuple(fl) => {
129 let fields = fl
130 .fields()
131 .enumerate()
132 .map(|(i, fd)| StructFieldData {
133 name: Name::new_tuple_field(i),
134 type_ref: TypeRef::from_ast_opt(fd.type_ref()),
135 })
136 .collect();
137 VariantDataInner::Tuple(fields)
138 }
139 ast::StructKind::Named(fl) => {
140 let fields = fl
141 .fields()
142 .map(|fd| StructFieldData {
143 name: fd.name().map(|n| n.as_name()).unwrap_or_else(Name::missing),
144 type_ref: TypeRef::from_ast_opt(fd.ascribed_type()),
145 })
146 .collect();
147 VariantDataInner::Struct(fields)
148 }
149 ast::StructKind::Unit => VariantDataInner::Unit,
150 };
151 VariantData(inner)
152 } 16 }
153} 17}
154 18
@@ -188,35 +52,3 @@ impl VariantDef {
188 } 52 }
189 } 53 }
190} 54}
191
192impl StructField {
193 pub(crate) fn source_impl(&self, db: &(impl DefDatabase + AstDatabase)) -> Source<FieldSource> {
194 let var_data = self.parent.variant_data(db);
195 let fields = var_data.fields().unwrap();
196 let ss;
197 let es;
198 let (file_id, struct_kind) = match self.parent {
199 VariantDef::Struct(s) => {
200 ss = s.source(db);
201 (ss.file_id, ss.ast.kind())
202 }
203 VariantDef::EnumVariant(e) => {
204 es = e.source(db);
205 (es.file_id, es.ast.kind())
206 }
207 };
208
209 let field_sources = match struct_kind {
210 ast::StructKind::Tuple(fl) => fl.fields().map(|it| FieldSource::Pos(it)).collect(),
211 ast::StructKind::Named(fl) => fl.fields().map(|it| FieldSource::Named(it)).collect(),
212 ast::StructKind::Unit => Vec::new(),
213 };
214 let ast = field_sources
215 .into_iter()
216 .zip(fields.iter())
217 .find(|(_syntax, (id, _))| *id == self.id)
218 .unwrap()
219 .0;
220 Source { file_id, ast }
221 }
222}