aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-25 15:41:08 +0100
committerJonas Schievink <[email protected]>2020-06-25 15:41:08 +0100
commit2a8fc9e6829c15a54e9094b940312e9485c6b79a (patch)
tree373d0816001592e8cfcb1a80803989f459c80ec1
parentd84b3ff6a1c42df0e349dc8ec3fc08e8c1251777 (diff)
adt.rs: fetch struct/union data from item tree
-rw-r--r--crates/ra_hir_def/src/adt.rs68
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};
14use crate::{ 14use 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};
26use 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
60impl StructData { 62impl 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
253fn 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
277fn 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}