diff options
Diffstat (limited to 'crates/ra_hir_def/src/adt.rs')
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 57 |
1 files changed, 39 insertions, 18 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 7fc4cd76e..be4b0accb 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -4,6 +4,7 @@ use std::sync::Arc; | |||
4 | 4 | ||
5 | use either::Either; | 5 | use either::Either; |
6 | use hir_expand::{ | 6 | use hir_expand::{ |
7 | hygiene::Hygiene, | ||
7 | name::{AsName, Name}, | 8 | name::{AsName, Name}, |
8 | InFile, | 9 | InFile, |
9 | }; | 10 | }; |
@@ -12,9 +13,9 @@ use ra_prof::profile; | |||
12 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; | 13 | use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; |
13 | 14 | ||
14 | use crate::{ | 15 | use crate::{ |
15 | db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, type_ref::TypeRef, | 16 | attr::Attrs, db::DefDatabase, src::HasChildSource, src::HasSource, trace::Trace, |
16 | visibility::RawVisibility, EnumId, LocalEnumVariantId, LocalStructFieldId, Lookup, StructId, | 17 | type_ref::TypeRef, visibility::RawVisibility, EnumId, HasModule, LocalEnumVariantId, |
17 | UnionId, VariantId, | 18 | LocalStructFieldId, Lookup, ModuleId, StructId, UnionId, VariantId, |
18 | }; | 19 | }; |
19 | 20 | ||
20 | /// Note that we use `StructData` for unions as well! | 21 | /// Note that we use `StructData` for unions as well! |
@@ -56,7 +57,8 @@ impl StructData { | |||
56 | let src = id.lookup(db).source(db); | 57 | let src = id.lookup(db).source(db); |
57 | 58 | ||
58 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | 59 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); |
59 | let variant_data = VariantData::new(db, src.map(|s| s.kind())); | 60 | let variant_data = |
61 | VariantData::new(db, src.map(|s| s.kind()), id.lookup(db).container.module(db)); | ||
60 | let variant_data = Arc::new(variant_data); | 62 | let variant_data = Arc::new(variant_data); |
61 | Arc::new(StructData { name, variant_data }) | 63 | Arc::new(StructData { name, variant_data }) |
62 | } | 64 | } |
@@ -70,6 +72,7 @@ impl StructData { | |||
70 | .map(ast::StructKind::Record) | 72 | .map(ast::StructKind::Record) |
71 | .unwrap_or(ast::StructKind::Unit) | 73 | .unwrap_or(ast::StructKind::Unit) |
72 | }), | 74 | }), |
75 | id.lookup(db).container.module(db), | ||
73 | ); | 76 | ); |
74 | let variant_data = Arc::new(variant_data); | 77 | let variant_data = Arc::new(variant_data); |
75 | Arc::new(StructData { name, variant_data }) | 78 | Arc::new(StructData { name, variant_data }) |
@@ -82,7 +85,7 @@ impl EnumData { | |||
82 | let src = e.lookup(db).source(db); | 85 | let src = e.lookup(db).source(db); |
83 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | 86 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); |
84 | let mut trace = Trace::new_for_arena(); | 87 | let mut trace = Trace::new_for_arena(); |
85 | lower_enum(db, &mut trace, &src); | 88 | lower_enum(db, &mut trace, &src, e.lookup(db).container.module(db)); |
86 | Arc::new(EnumData { name, variants: trace.into_arena() }) | 89 | Arc::new(EnumData { name, variants: trace.into_arena() }) |
87 | } | 90 | } |
88 | 91 | ||
@@ -98,7 +101,7 @@ impl HasChildSource for EnumId { | |||
98 | fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> { | 101 | fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> { |
99 | let src = self.lookup(db).source(db); | 102 | let src = self.lookup(db).source(db); |
100 | let mut trace = Trace::new_for_map(); | 103 | let mut trace = Trace::new_for_map(); |
101 | lower_enum(db, &mut trace, &src); | 104 | lower_enum(db, &mut trace, &src, self.lookup(db).container.module(db)); |
102 | src.with_value(trace.into_map()) | 105 | src.with_value(trace.into_map()) |
103 | } | 106 | } |
104 | } | 107 | } |
@@ -107,22 +110,23 @@ fn lower_enum( | |||
107 | db: &dyn DefDatabase, | 110 | db: &dyn DefDatabase, |
108 | trace: &mut Trace<EnumVariantData, ast::EnumVariant>, | 111 | trace: &mut Trace<EnumVariantData, ast::EnumVariant>, |
109 | ast: &InFile<ast::EnumDef>, | 112 | ast: &InFile<ast::EnumDef>, |
113 | module_id: ModuleId, | ||
110 | ) { | 114 | ) { |
111 | for var in ast.value.variant_list().into_iter().flat_map(|it| it.variants()) { | 115 | for var in ast.value.variant_list().into_iter().flat_map(|it| it.variants()) { |
112 | trace.alloc( | 116 | trace.alloc( |
113 | || var.clone(), | 117 | || var.clone(), |
114 | || EnumVariantData { | 118 | || EnumVariantData { |
115 | name: var.name().map_or_else(Name::missing, |it| it.as_name()), | 119 | name: var.name().map_or_else(Name::missing, |it| it.as_name()), |
116 | variant_data: Arc::new(VariantData::new(db, ast.with_value(var.kind()))), | 120 | variant_data: Arc::new(VariantData::new(db, ast.with_value(var.kind()), module_id)), |
117 | }, | 121 | }, |
118 | ); | 122 | ); |
119 | } | 123 | } |
120 | } | 124 | } |
121 | 125 | ||
122 | impl VariantData { | 126 | impl VariantData { |
123 | fn new(db: &dyn DefDatabase, flavor: InFile<ast::StructKind>) -> Self { | 127 | fn new(db: &dyn DefDatabase, flavor: InFile<ast::StructKind>, module_id: ModuleId) -> Self { |
124 | let mut trace = Trace::new_for_arena(); | 128 | let mut trace = Trace::new_for_arena(); |
125 | match lower_struct(db, &mut trace, &flavor) { | 129 | match lower_struct(db, &mut trace, &flavor, module_id) { |
126 | StructKind::Tuple => VariantData::Tuple(trace.into_arena()), | 130 | StructKind::Tuple => VariantData::Tuple(trace.into_arena()), |
127 | StructKind::Record => VariantData::Record(trace.into_arena()), | 131 | StructKind::Record => VariantData::Record(trace.into_arena()), |
128 | StructKind::Unit => VariantData::Unit, | 132 | StructKind::Unit => VariantData::Unit, |
@@ -155,22 +159,27 @@ impl HasChildSource for VariantId { | |||
155 | type Value = Either<ast::TupleFieldDef, ast::RecordFieldDef>; | 159 | type Value = Either<ast::TupleFieldDef, ast::RecordFieldDef>; |
156 | 160 | ||
157 | fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> { | 161 | fn child_source(&self, db: &dyn DefDatabase) -> InFile<ArenaMap<Self::ChildId, Self::Value>> { |
158 | let src = match self { | 162 | let (src, module_id) = match self { |
159 | VariantId::EnumVariantId(it) => { | 163 | VariantId::EnumVariantId(it) => { |
160 | // I don't really like the fact that we call into parent source | 164 | // I don't really like the fact that we call into parent source |
161 | // here, this might add to more queries then necessary. | 165 | // here, this might add to more queries then necessary. |
162 | let src = it.parent.child_source(db); | 166 | let src = it.parent.child_source(db); |
163 | src.map(|map| map[it.local_id].kind()) | 167 | (src.map(|map| map[it.local_id].kind()), it.parent.lookup(db).container.module(db)) |
164 | } | 168 | } |
165 | VariantId::StructId(it) => it.lookup(db).source(db).map(|it| it.kind()), | 169 | VariantId::StructId(it) => { |
166 | VariantId::UnionId(it) => it.lookup(db).source(db).map(|it| { | 170 | (it.lookup(db).source(db).map(|it| it.kind()), it.lookup(db).container.module(db)) |
167 | it.record_field_def_list() | 171 | } |
168 | .map(ast::StructKind::Record) | 172 | VariantId::UnionId(it) => ( |
169 | .unwrap_or(ast::StructKind::Unit) | 173 | it.lookup(db).source(db).map(|it| { |
170 | }), | 174 | it.record_field_def_list() |
175 | .map(ast::StructKind::Record) | ||
176 | .unwrap_or(ast::StructKind::Unit) | ||
177 | }), | ||
178 | it.lookup(db).container.module(db), | ||
179 | ), | ||
171 | }; | 180 | }; |
172 | let mut trace = Trace::new_for_map(); | 181 | let mut trace = Trace::new_for_map(); |
173 | lower_struct(db, &mut trace, &src); | 182 | lower_struct(db, &mut trace, &src, module_id); |
174 | src.with_value(trace.into_map()) | 183 | src.with_value(trace.into_map()) |
175 | } | 184 | } |
176 | } | 185 | } |
@@ -186,10 +195,17 @@ fn lower_struct( | |||
186 | db: &dyn DefDatabase, | 195 | db: &dyn DefDatabase, |
187 | trace: &mut Trace<StructFieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>, | 196 | trace: &mut Trace<StructFieldData, Either<ast::TupleFieldDef, ast::RecordFieldDef>>, |
188 | ast: &InFile<ast::StructKind>, | 197 | ast: &InFile<ast::StructKind>, |
198 | module_id: ModuleId, | ||
189 | ) -> StructKind { | 199 | ) -> StructKind { |
200 | let crate_graph = db.crate_graph(); | ||
190 | match &ast.value { | 201 | match &ast.value { |
191 | ast::StructKind::Tuple(fl) => { | 202 | ast::StructKind::Tuple(fl) => { |
192 | for (i, fd) in fl.fields().enumerate() { | 203 | for (i, fd) in fl.fields().enumerate() { |
204 | let attrs = Attrs::new(&fd, &Hygiene::new(db.upcast(), ast.file_id)); | ||
205 | if !attrs.is_cfg_enabled(&crate_graph[module_id.krate].cfg_options) { | ||
206 | continue; | ||
207 | } | ||
208 | |||
193 | trace.alloc( | 209 | trace.alloc( |
194 | || Either::Left(fd.clone()), | 210 | || Either::Left(fd.clone()), |
195 | || StructFieldData { | 211 | || StructFieldData { |
@@ -203,6 +219,11 @@ fn lower_struct( | |||
203 | } | 219 | } |
204 | ast::StructKind::Record(fl) => { | 220 | ast::StructKind::Record(fl) => { |
205 | for fd in fl.fields() { | 221 | for fd in fl.fields() { |
222 | let attrs = Attrs::new(&fd, &Hygiene::new(db.upcast(), ast.file_id)); | ||
223 | if !attrs.is_cfg_enabled(&crate_graph[module_id.krate].cfg_options) { | ||
224 | continue; | ||
225 | } | ||
226 | |||
206 | trace.alloc( | 227 | trace.alloc( |
207 | || Either::Right(fd.clone()), | 228 | || Either::Right(fd.clone()), |
208 | || StructFieldData { | 229 | || StructFieldData { |