diff options
author | Jonas Schievink <[email protected]> | 2020-06-25 15:41:08 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-06-25 15:41:08 +0100 |
commit | 2a8fc9e6829c15a54e9094b940312e9485c6b79a (patch) | |
tree | 373d0816001592e8cfcb1a80803989f459c80ec1 | |
parent | d84b3ff6a1c42df0e349dc8ec3fc08e8c1251777 (diff) |
adt.rs: fetch struct/union data from item tree
-rw-r--r-- | crates/ra_hir_def/src/adt.rs | 68 |
1 files changed, 49 insertions, 19 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs index 2bc34d449..65546b339 100644 --- a/crates/ra_hir_def/src/adt.rs +++ b/crates/ra_hir_def/src/adt.rs | |||
@@ -14,6 +14,7 @@ use ra_syntax::ast::{self, NameOwner, TypeAscriptionOwner, VisibilityOwner}; | |||
14 | use crate::{ | 14 | use crate::{ |
15 | body::{CfgExpander, LowerCtx}, | 15 | body::{CfgExpander, LowerCtx}, |
16 | db::DefDatabase, | 16 | db::DefDatabase, |
17 | item_tree::{Field, Fields, ItemTree}, | ||
17 | src::HasChildSource, | 18 | src::HasChildSource, |
18 | src::HasSource, | 19 | src::HasSource, |
19 | trace::Trace, | 20 | trace::Trace, |
@@ -22,6 +23,7 @@ use crate::{ | |||
22 | EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, | 23 | EnumId, HasModule, LocalEnumVariantId, LocalFieldId, Lookup, ModuleId, StructId, UnionId, |
23 | VariantId, | 24 | VariantId, |
24 | }; | 25 | }; |
26 | use ra_cfg::CfgOptions; | ||
25 | 27 | ||
26 | /// Note that we use `StructData` for unions as well! | 28 | /// Note that we use `StructData` for unions as well! |
27 | #[derive(Debug, Clone, PartialEq, Eq)] | 29 | #[derive(Debug, Clone, PartialEq, Eq)] |
@@ -59,28 +61,24 @@ pub struct FieldData { | |||
59 | 61 | ||
60 | impl StructData { | 62 | impl StructData { |
61 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { | 63 | pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { |
62 | let src = id.lookup(db).source(db); | 64 | let loc = id.lookup(db); |
65 | let item_tree = db.item_tree(loc.id.file_id); | ||
66 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); | ||
63 | 67 | ||
64 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | 68 | let strukt = &item_tree[loc.id.value]; |
65 | let variant_data = | 69 | let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields); |
66 | VariantData::new(db, src.map(|s| s.kind()), id.lookup(db).container.module(db)); | 70 | |
67 | let variant_data = Arc::new(variant_data); | 71 | Arc::new(StructData { name: strukt.name.clone(), variant_data: Arc::new(variant_data) }) |
68 | Arc::new(StructData { name, variant_data }) | ||
69 | } | 72 | } |
70 | pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { | 73 | pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { |
71 | let src = id.lookup(db).source(db); | 74 | let loc = id.lookup(db); |
72 | let name = src.value.name().map_or_else(Name::missing, |n| n.as_name()); | 75 | let item_tree = db.item_tree(loc.id.file_id); |
73 | let variant_data = VariantData::new( | 76 | let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); |
74 | db, | 77 | |
75 | src.map(|s| { | 78 | let union = &item_tree[loc.id.value]; |
76 | s.record_field_def_list() | 79 | let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields); |
77 | .map(ast::StructKind::Record) | 80 | |
78 | .unwrap_or(ast::StructKind::Unit) | 81 | Arc::new(StructData { name: union.name.clone(), variant_data: Arc::new(variant_data) }) |
79 | }), | ||
80 | id.lookup(db).container.module(db), | ||
81 | ); | ||
82 | let variant_data = Arc::new(variant_data); | ||
83 | Arc::new(StructData { name, variant_data }) | ||
84 | } | 82 | } |
85 | } | 83 | } |
86 | 84 | ||
@@ -251,3 +249,35 @@ fn lower_struct( | |||
251 | ast::StructKind::Unit => StructKind::Unit, | 249 | ast::StructKind::Unit => StructKind::Unit, |
252 | } | 250 | } |
253 | } | 251 | } |
252 | |||
253 | fn lower_fields(item_tree: &ItemTree, cfg_options: &CfgOptions, fields: &Fields) -> VariantData { | ||
254 | match fields { | ||
255 | Fields::Record(flds) => { | ||
256 | let mut arena = Arena::new(); | ||
257 | for field_id in flds.clone() { | ||
258 | if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { | ||
259 | arena.alloc(lower_field(item_tree, &item_tree[field_id])); | ||
260 | } | ||
261 | } | ||
262 | VariantData::Record(arena) | ||
263 | } | ||
264 | Fields::Tuple(flds) => { | ||
265 | let mut arena = Arena::new(); | ||
266 | for field_id in flds.clone() { | ||
267 | if item_tree.attrs(field_id.into()).is_cfg_enabled(cfg_options) { | ||
268 | arena.alloc(lower_field(item_tree, &item_tree[field_id])); | ||
269 | } | ||
270 | } | ||
271 | VariantData::Tuple(arena) | ||
272 | } | ||
273 | Fields::Unit => VariantData::Unit, | ||
274 | } | ||
275 | } | ||
276 | |||
277 | fn lower_field(item_tree: &ItemTree, field: &Field) -> FieldData { | ||
278 | FieldData { | ||
279 | name: field.name.clone(), | ||
280 | type_ref: field.type_ref.clone(), | ||
281 | visibility: item_tree[field.visibility].clone(), | ||
282 | } | ||
283 | } | ||