diff options
author | Aleksey Kladov <[email protected]> | 2019-10-31 13:40:36 +0000 |
---|---|---|
committer | Aleksey Kladov <[email protected]> | 2019-10-31 13:40:36 +0000 |
commit | 09f9733ca67b74057c55b6e96f38223a73db6a6e (patch) | |
tree | 1d1ca3aeb17592c9aaa2823f1548b211141b9e10 /crates/ra_hir/src/adt.rs | |
parent | d067afb064a7fa67b172abf561b7d80740cd6f18 (diff) |
move struct & enum data to hir_def
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 176 |
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 | ||
4 | use std::sync::Arc; | 4 | use std::sync::Arc; |
5 | 5 | ||
6 | use hir_def::{type_ref::TypeRef, LocalEnumVariantId}; | 6 | use hir_def::adt::VariantData; |
7 | use hir_expand::name::AsName; | ||
8 | use ra_arena::{impl_arena_id, Arena, RawId}; | ||
9 | use ra_syntax::ast::{self, NameOwner, StructKind, TypeAscriptionOwner}; | ||
10 | 7 | ||
11 | use crate::{ | 8 | use 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 | ||
16 | impl Struct { | 13 | impl 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)] | ||
24 | pub struct StructData { | ||
25 | pub(crate) name: Option<Name>, | ||
26 | pub(crate) variant_data: Arc<VariantData>, | ||
27 | } | ||
28 | |||
29 | impl 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 | |||
46 | fn variants(enum_def: &ast::EnumDef) -> impl Iterator<Item = ast::EnumVariant> { | ||
47 | enum_def.variant_list().into_iter().flat_map(|it| it.variants()) | ||
48 | } | ||
49 | |||
50 | impl 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)] | ||
69 | pub struct EnumData { | ||
70 | pub(crate) name: Option<Name>, | ||
71 | pub(crate) variants: Arena<LocalEnumVariantId, EnumVariantData>, | ||
72 | } | ||
73 | |||
74 | impl 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)] | ||
89 | pub(crate) struct EnumVariantData { | ||
90 | pub(crate) name: Option<Name>, | ||
91 | variant_data: Arc<VariantData>, | ||
92 | } | ||
93 | |||
94 | #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] | ||
95 | pub(crate) struct StructFieldId(RawId); | ||
96 | impl_arena_id!(StructFieldId); | ||
97 | |||
98 | /// A single field of an enum variant or struct | ||
99 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
100 | pub 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)] | ||
107 | pub(crate) struct VariantData(VariantDataInner); | ||
108 | |||
109 | #[derive(Debug, Clone, PartialEq, Eq)] | ||
110 | enum VariantDataInner { | ||
111 | Struct(Arena<StructFieldId, StructFieldData>), | ||
112 | Tuple(Arena<StructFieldId, StructFieldData>), | ||
113 | Unit, | ||
114 | } | ||
115 | |||
116 | impl 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 | |||
125 | impl 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 | |||
192 | impl 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 | } | ||