aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir/src/adt.rs
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2018-12-25 20:40:33 +0000
committerFlorian Diebold <[email protected]>2018-12-25 20:40:33 +0000
commitbc745a139674f289386f3081458793f756cab5b9 (patch)
tree518c38ce87807c76644b512ce0213dd01e43614a /crates/ra_hir/src/adt.rs
parentcdca39706121b2d1734a94938a2372da881e10c6 (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.rs71
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}};
5use crate::{ 5use 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
12pub struct Struct { 11pub struct Struct {
@@ -42,15 +41,11 @@ pub struct StructData {
42} 41}
43 42
44impl StructData { 43impl 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
89impl EnumData { 84impl 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)]
116pub struct StructField { 107pub struct StructField {
117 name: SmolStr, 108 name: SmolStr,
118 ty: Ty, 109 type_ref: TypeRef,
119} 110}
120 111
121impl StructField { 112impl 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
138impl VariantData { 129impl 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] {