aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/adt.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/adt.rs')
-rw-r--r--crates/ra_hir_def/src/adt.rs56
1 files changed, 52 insertions, 4 deletions
diff --git a/crates/ra_hir_def/src/adt.rs b/crates/ra_hir_def/src/adt.rs
index 6cb56a1cd..6d59c8642 100644
--- a/crates/ra_hir_def/src/adt.rs
+++ b/crates/ra_hir_def/src/adt.rs
@@ -9,11 +9,13 @@ use hir_expand::{
9}; 9};
10use ra_arena::{map::ArenaMap, Arena}; 10use ra_arena::{map::ArenaMap, Arena};
11use ra_syntax::ast::{self, NameOwner, VisibilityOwner}; 11use ra_syntax::ast::{self, NameOwner, VisibilityOwner};
12use tt::{Delimiter, DelimiterKind, Leaf, Subtree, TokenTree};
12 13
13use crate::{ 14use crate::{
15 attr::AttrInput,
14 body::{CfgExpander, LowerCtx}, 16 body::{CfgExpander, LowerCtx},
15 db::DefDatabase, 17 db::DefDatabase,
16 item_tree::{Field, Fields, ItemTree}, 18 item_tree::{AttrOwner, Field, Fields, ItemTree, ModItem},
17 src::HasChildSource, 19 src::HasChildSource,
18 src::HasSource, 20 src::HasSource,
19 trace::Trace, 21 trace::Trace,
@@ -29,6 +31,7 @@ use ra_cfg::CfgOptions;
29pub struct StructData { 31pub struct StructData {
30 pub name: Name, 32 pub name: Name,
31 pub variant_data: Arc<VariantData>, 33 pub variant_data: Arc<VariantData>,
34 pub repr: Option<ReprKind>,
32} 35}
33 36
34#[derive(Debug, Clone, PartialEq, Eq)] 37#[derive(Debug, Clone, PartialEq, Eq)]
@@ -58,26 +61,71 @@ pub struct FieldData {
58 pub visibility: RawVisibility, 61 pub visibility: RawVisibility,
59} 62}
60 63
64#[derive(Debug, Clone, PartialEq, Eq)]
65pub enum ReprKind {
66 Packed,
67 Other,
68}
69
70fn repr_from_value(item_tree: &ItemTree, of: AttrOwner) -> Option<ReprKind> {
71 item_tree.attrs(of).iter().find_map(|a| {
72 if a.path.segments[0].to_string() == "repr" {
73 if let Some(AttrInput::TokenTree(subtree)) = &a.input {
74 parse_repr_tt(subtree)
75 } else {
76 None
77 }
78 } else {
79 None
80 }
81 })
82}
83
84fn parse_repr_tt(tt: &Subtree) -> Option<ReprKind> {
85 match tt.delimiter {
86 Some(Delimiter { kind: DelimiterKind::Parenthesis, .. }) => {}
87 _ => return None,
88 }
89
90 let mut it = tt.token_trees.iter();
91 match it.next() {
92 None => None,
93 Some(TokenTree::Leaf(Leaf::Ident(ident))) if ident.text == "packed" => {
94 Some(ReprKind::Packed)
95 }
96 _ => Some(ReprKind::Other),
97 }
98}
99
61impl StructData { 100impl StructData {
62 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> { 101 pub(crate) fn struct_data_query(db: &dyn DefDatabase, id: StructId) -> Arc<StructData> {
63 let loc = id.lookup(db); 102 let loc = id.lookup(db);
64 let item_tree = db.item_tree(loc.id.file_id); 103 let item_tree = db.item_tree(loc.id.file_id);
104 let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into());
65 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 105 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
66 106
67 let strukt = &item_tree[loc.id.value]; 107 let strukt = &item_tree[loc.id.value];
68 let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields); 108 let variant_data = lower_fields(&item_tree, &cfg_options, &strukt.fields);
69 109 Arc::new(StructData {
70 Arc::new(StructData { name: strukt.name.clone(), variant_data: Arc::new(variant_data) }) 110 name: strukt.name.clone(),
111 variant_data: Arc::new(variant_data),
112 repr,
113 })
71 } 114 }
72 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> { 115 pub(crate) fn union_data_query(db: &dyn DefDatabase, id: UnionId) -> Arc<StructData> {
73 let loc = id.lookup(db); 116 let loc = id.lookup(db);
74 let item_tree = db.item_tree(loc.id.file_id); 117 let item_tree = db.item_tree(loc.id.file_id);
118 let repr = repr_from_value(&item_tree, ModItem::from(loc.id.value).into());
75 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone(); 119 let cfg_options = db.crate_graph()[loc.container.module(db).krate].cfg_options.clone();
76 120
77 let union = &item_tree[loc.id.value]; 121 let union = &item_tree[loc.id.value];
78 let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields); 122 let variant_data = lower_fields(&item_tree, &cfg_options, &union.fields);
79 123
80 Arc::new(StructData { name: union.name.clone(), variant_data: Arc::new(variant_data) }) 124 Arc::new(StructData {
125 name: union.name.clone(),
126 variant_data: Arc::new(variant_data),
127 repr,
128 })
81 } 129 }
82} 130}
83 131