diff options
author | Florian Diebold <[email protected]> | 2018-12-25 20:40:33 +0000 |
---|---|---|
committer | Florian Diebold <[email protected]> | 2018-12-25 20:40:33 +0000 |
commit | bc745a139674f289386f3081458793f756cab5b9 (patch) | |
tree | 518c38ce87807c76644b512ce0213dd01e43614a /crates/ra_hir/src/adt.rs | |
parent | cdca39706121b2d1734a94938a2372da881e10c6 (diff) |
Resolve field types lazily
I.e. not already when getting the HIR for the struct.
Diffstat (limited to 'crates/ra_hir/src/adt.rs')
-rw-r--r-- | crates/ra_hir/src/adt.rs | 71 |
1 files changed, 29 insertions, 42 deletions
diff --git a/crates/ra_hir/src/adt.rs b/crates/ra_hir/src/adt.rs index dae04d258..65c461148 100644 --- a/crates/ra_hir/src/adt.rs +++ b/crates/ra_hir/src/adt.rs | |||
@@ -5,8 +5,7 @@ use ra_syntax::{SmolStr, ast::{self, NameOwner, StructFlavor}}; | |||
5 | use crate::{ | 5 | use crate::{ |
6 | DefId, Cancelable, | 6 | DefId, Cancelable, |
7 | db::{HirDatabase}, | 7 | db::{HirDatabase}, |
8 | module::Module, | 8 | type_ref::TypeRef, |
9 | ty::{Ty}, | ||
10 | }; | 9 | }; |
11 | 10 | ||
12 | pub struct Struct { | 11 | pub struct Struct { |
@@ -42,15 +41,11 @@ pub struct StructData { | |||
42 | } | 41 | } |
43 | 42 | ||
44 | impl StructData { | 43 | impl StructData { |
45 | pub(crate) fn new( | 44 | pub(crate) fn new(struct_def: ast::StructDef) -> StructData { |
46 | db: &impl HirDatabase, | ||
47 | module: &Module, | ||
48 | struct_def: ast::StructDef, | ||
49 | ) -> Cancelable<StructData> { | ||
50 | let name = struct_def.name().map(|n| n.text()); | 45 | let name = struct_def.name().map(|n| n.text()); |
51 | let variant_data = VariantData::new(db, module, struct_def.flavor())?; | 46 | let variant_data = VariantData::new(struct_def.flavor()); |
52 | let variant_data = Arc::new(variant_data); | 47 | let variant_data = Arc::new(variant_data); |
53 | Ok(StructData { name, variant_data }) | 48 | StructData { name, variant_data } |
54 | } | 49 | } |
55 | 50 | ||
56 | pub fn name(&self) -> Option<&SmolStr> { | 51 | pub fn name(&self) -> Option<&SmolStr> { |
@@ -87,27 +82,23 @@ pub struct EnumData { | |||
87 | } | 82 | } |
88 | 83 | ||
89 | impl EnumData { | 84 | impl EnumData { |
90 | pub(crate) fn new( | 85 | pub(crate) fn new(enum_def: ast::EnumDef) -> Self { |
91 | db: &impl HirDatabase, | ||
92 | module: &Module, | ||
93 | enum_def: ast::EnumDef, | ||
94 | ) -> Cancelable<Self> { | ||
95 | let name = enum_def.name().map(|n| n.text()); | 86 | let name = enum_def.name().map(|n| n.text()); |
96 | let variants = if let Some(evl) = enum_def.variant_list() { | 87 | let variants = if let Some(evl) = enum_def.variant_list() { |
97 | evl.variants() | 88 | evl.variants() |
98 | .map(|v| { | 89 | .map(|v| { |
99 | Ok(( | 90 | ( |
100 | v.name() | 91 | v.name() |
101 | .map(|n| n.text()) | 92 | .map(|n| n.text()) |
102 | .unwrap_or_else(|| SmolStr::new("[error]")), | 93 | .unwrap_or_else(|| SmolStr::new("[error]")), |
103 | Arc::new(VariantData::new(db, module, v.flavor())?), | 94 | Arc::new(VariantData::new(v.flavor())), |
104 | )) | 95 | ) |
105 | }) | 96 | }) |
106 | .collect::<Cancelable<_>>()? | 97 | .collect() |
107 | } else { | 98 | } else { |
108 | Vec::new() | 99 | Vec::new() |
109 | }; | 100 | }; |
110 | Ok(EnumData { name, variants }) | 101 | EnumData { name, variants } |
111 | } | 102 | } |
112 | } | 103 | } |
113 | 104 | ||
@@ -115,15 +106,15 @@ impl EnumData { | |||
115 | #[derive(Debug, Clone, PartialEq, Eq)] | 106 | #[derive(Debug, Clone, PartialEq, Eq)] |
116 | pub struct StructField { | 107 | pub struct StructField { |
117 | name: SmolStr, | 108 | name: SmolStr, |
118 | ty: Ty, | 109 | type_ref: TypeRef, |
119 | } | 110 | } |
120 | 111 | ||
121 | impl StructField { | 112 | impl StructField { |
122 | pub fn name(&self) -> SmolStr { | 113 | pub fn name(&self) -> SmolStr { |
123 | self.name.clone() | 114 | self.name.clone() |
124 | } | 115 | } |
125 | pub fn ty(&self) -> Ty { | 116 | pub fn type_ref(&self) -> &TypeRef { |
126 | self.ty.clone() | 117 | &self.type_ref |
127 | } | 118 | } |
128 | } | 119 | } |
129 | 120 | ||
@@ -136,45 +127,41 @@ pub enum VariantData { | |||
136 | } | 127 | } |
137 | 128 | ||
138 | impl VariantData { | 129 | impl VariantData { |
139 | pub fn new(db: &impl HirDatabase, module: &Module, flavor: StructFlavor) -> Cancelable<Self> { | 130 | pub fn new(flavor: StructFlavor) -> Self { |
140 | Ok(match flavor { | 131 | match flavor { |
141 | StructFlavor::Tuple(fl) => { | 132 | StructFlavor::Tuple(fl) => { |
142 | let fields = fl | 133 | let fields = fl |
143 | .fields() | 134 | .fields() |
144 | .enumerate() | 135 | .enumerate() |
145 | .map(|(i, fd)| { | 136 | .map(|(i, fd)| StructField { |
146 | Ok(StructField { | 137 | name: SmolStr::new(i.to_string()), |
147 | name: SmolStr::new(i.to_string()), | 138 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), |
148 | ty: Ty::from_ast_opt(db, &module, fd.type_ref())?, | ||
149 | }) | ||
150 | }) | 139 | }) |
151 | .collect::<Cancelable<_>>()?; | 140 | .collect(); |
152 | VariantData::Tuple(fields) | 141 | VariantData::Tuple(fields) |
153 | } | 142 | } |
154 | StructFlavor::Named(fl) => { | 143 | StructFlavor::Named(fl) => { |
155 | let fields = fl | 144 | let fields = fl |
156 | .fields() | 145 | .fields() |
157 | .map(|fd| { | 146 | .map(|fd| StructField { |
158 | Ok(StructField { | 147 | name: fd |
159 | name: fd | 148 | .name() |
160 | .name() | 149 | .map(|n| n.text()) |
161 | .map(|n| n.text()) | 150 | .unwrap_or_else(|| SmolStr::new("[error]")), |
162 | .unwrap_or_else(|| SmolStr::new("[error]")), | 151 | type_ref: TypeRef::from_ast_opt(fd.type_ref()), |
163 | ty: Ty::from_ast_opt(db, &module, fd.type_ref())?, | ||
164 | }) | ||
165 | }) | 152 | }) |
166 | .collect::<Cancelable<_>>()?; | 153 | .collect(); |
167 | VariantData::Struct(fields) | 154 | VariantData::Struct(fields) |
168 | } | 155 | } |
169 | StructFlavor::Unit => VariantData::Unit, | 156 | StructFlavor::Unit => VariantData::Unit, |
170 | }) | 157 | } |
171 | } | 158 | } |
172 | 159 | ||
173 | pub(crate) fn get_field_ty(&self, field_name: &str) -> Option<Ty> { | 160 | pub(crate) fn get_field_type_ref(&self, field_name: &str) -> Option<&TypeRef> { |
174 | self.fields() | 161 | self.fields() |
175 | .iter() | 162 | .iter() |
176 | .find(|f| f.name == field_name) | 163 | .find(|f| f.name == field_name) |
177 | .map(|f| f.ty.clone()) | 164 | .map(|f| &f.type_ref) |
178 | } | 165 | } |
179 | 166 | ||
180 | pub fn fields(&self) -> &[StructField] { | 167 | pub fn fields(&self) -> &[StructField] { |