aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def
diff options
context:
space:
mode:
authorJonas Schievink <[email protected]>2020-06-25 13:39:27 +0100
committerJonas Schievink <[email protected]>2020-06-25 13:39:27 +0100
commitd84b3ff6a1c42df0e349dc8ec3fc08e8c1251777 (patch)
treec39b8534ceaaeb34ec99c973afa738f6f44dd6a4 /crates/ra_hir_def
parent9ba772657950cb8353f37bc2576b78c4f0c8996f (diff)
Collect field/variant attrs in ItemTree
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r--crates/ra_hir_def/src/attr.rs2
-rw-r--r--crates/ra_hir_def/src/data.rs4
-rw-r--r--crates/ra_hir_def/src/item_tree.rs25
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs23
-rw-r--r--crates/ra_hir_def/src/item_tree/tests.rs2
-rw-r--r--crates/ra_hir_def/src/nameres/collector.rs4
6 files changed, 40 insertions, 20 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs
index 197737ffc..e228e2145 100644
--- a/crates/ra_hir_def/src/attr.rs
+++ b/crates/ra_hir_def/src/attr.rs
@@ -208,5 +208,5 @@ where
208fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs { 208fn attrs_from_item_tree<N: ItemTreeNode>(id: ItemTreeId<N>, db: &dyn DefDatabase) -> Attrs {
209 let tree = db.item_tree(id.file_id); 209 let tree = db.item_tree(id.file_id);
210 let mod_item = N::id_to_mod_item(id.value); 210 let mod_item = N::id_to_mod_item(id.value);
211 tree.attrs(mod_item).clone() 211 tree.attrs(mod_item.into()).clone()
212} 212}
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs
index f9e5701db..282ade2a3 100644
--- a/crates/ra_hir_def/src/data.rs
+++ b/crates/ra_hir_def/src/data.rs
@@ -40,7 +40,7 @@ impl FunctionData {
40 name: func.name.clone(), 40 name: func.name.clone(),
41 params: func.params.to_vec(), 41 params: func.params.to_vec(),
42 ret_type: func.ret_type.clone(), 42 ret_type: func.ret_type.clone(),
43 attrs: item_tree.attrs(loc.id.value.into()).clone(), 43 attrs: item_tree.attrs(ModItem::from(loc.id.value).into()).clone(),
44 has_self_param: func.has_self_param, 44 has_self_param: func.has_self_param,
45 is_unsafe: func.is_unsafe, 45 is_unsafe: func.is_unsafe,
46 visibility: item_tree[func.visibility].clone(), 46 visibility: item_tree[func.visibility].clone(),
@@ -224,7 +224,7 @@ fn collect_items(
224 match item { 224 match item {
225 AssocItem::Function(id) => { 225 AssocItem::Function(id) => {
226 let item = &item_tree[id]; 226 let item = &item_tree[id];
227 let attrs = item_tree.attrs(id.into()); 227 let attrs = item_tree.attrs(ModItem::from(id).into());
228 if !attrs.is_cfg_enabled(&cfg_options) { 228 if !attrs.is_cfg_enabled(&cfg_options) {
229 continue; 229 continue;
230 } 230 }
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs
index f99e05432..fd874750e 100644
--- a/crates/ra_hir_def/src/item_tree.rs
+++ b/crates/ra_hir_def/src/item_tree.rs
@@ -178,8 +178,8 @@ impl ItemTree {
178 self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY) 178 self.attrs.get(&AttrOwner::TopLevel).unwrap_or(&Attrs::EMPTY)
179 } 179 }
180 180
181 pub fn attrs(&self, of: ModItem) -> &Attrs { 181 pub fn attrs(&self, of: AttrOwner) -> &Attrs {
182 self.attrs.get(&AttrOwner::ModItem(of)).unwrap_or(&Attrs::EMPTY) 182 self.attrs.get(&of).unwrap_or(&Attrs::EMPTY)
183 } 183 }
184 184
185 /// Returns the lowered inner items that `ast` corresponds to. 185 /// Returns the lowered inner items that `ast` corresponds to.
@@ -282,15 +282,32 @@ struct ItemTreeData {
282} 282}
283 283
284#[derive(Debug, Eq, PartialEq, Hash)] 284#[derive(Debug, Eq, PartialEq, Hash)]
285enum AttrOwner { 285pub enum AttrOwner {
286 /// Attributes on an item. 286 /// Attributes on an item.
287 ModItem(ModItem), 287 ModItem(ModItem),
288 /// Inner attributes of the source file. 288 /// Inner attributes of the source file.
289 TopLevel, 289 TopLevel,
290
291 Variant(Idx<Variant>),
292 Field(Idx<Field>),
290 // FIXME: Store variant and field attrs, and stop reparsing them in `attrs_query`. 293 // FIXME: Store variant and field attrs, and stop reparsing them in `attrs_query`.
291} 294}
292 295
293/// Trait implemented by all nodes in the item tree. 296macro_rules! from_attrs {
297 ( $( $var:ident($t:ty) ),+ ) => {
298 $(
299 impl From<$t> for AttrOwner {
300 fn from(t: $t) -> AttrOwner {
301 AttrOwner::$var(t)
302 }
303 }
304 )+
305 };
306}
307
308from_attrs!(ModItem(ModItem), Variant(Idx<Variant>), Field(Idx<Field>));
309
310/// Trait implemented by all item nodes in the item tree.
294pub trait ItemTreeNode: Clone { 311pub trait ItemTreeNode: Clone {
295 type Source: AstNode + Into<ast::ModuleItem>; 312 type Source: AstNode + Into<ast::ModuleItem>;
296 313
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index e2e00323c..230e1f768 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -126,15 +126,15 @@ impl Ctx {
126 126
127 if !attrs.is_empty() { 127 if !attrs.is_empty() {
128 for item in items.iter().flat_map(|items| &items.0) { 128 for item in items.iter().flat_map(|items| &items.0) {
129 self.add_attrs(*item, attrs.clone()); 129 self.add_attrs((*item).into(), attrs.clone());
130 } 130 }
131 } 131 }
132 132
133 items 133 items
134 } 134 }
135 135
136 fn add_attrs(&mut self, item: ModItem, attrs: Attrs) { 136 fn add_attrs(&mut self, item: AttrOwner, attrs: Attrs) {
137 match self.tree.attrs.entry(AttrOwner::ModItem(item)) { 137 match self.tree.attrs.entry(item) {
138 Entry::Occupied(mut entry) => { 138 Entry::Occupied(mut entry) => {
139 *entry.get_mut() = entry.get().merge(attrs); 139 *entry.get_mut() = entry.get().merge(attrs);
140 } 140 }
@@ -200,7 +200,8 @@ impl Ctx {
200 let start = self.next_field_idx(); 200 let start = self.next_field_idx();
201 for field in fields.fields() { 201 for field in fields.fields() {
202 if let Some(data) = self.lower_record_field(&field) { 202 if let Some(data) = self.lower_record_field(&field) {
203 self.data().fields.alloc(data); 203 let idx = self.data().fields.alloc(data);
204 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
204 } 205 }
205 } 206 }
206 let end = self.next_field_idx(); 207 let end = self.next_field_idx();
@@ -219,7 +220,8 @@ impl Ctx {
219 let start = self.next_field_idx(); 220 let start = self.next_field_idx();
220 for (i, field) in fields.fields().enumerate() { 221 for (i, field) in fields.fields().enumerate() {
221 if let Some(data) = self.lower_tuple_field(i, &field) { 222 if let Some(data) = self.lower_tuple_field(i, &field) {
222 self.data().fields.alloc(data); 223 let idx = self.data().fields.alloc(data);
224 self.add_attrs(idx.into(), Attrs::new(&field, &self.hygiene));
223 } 225 }
224 } 226 }
225 let end = self.next_field_idx(); 227 let end = self.next_field_idx();
@@ -266,7 +268,8 @@ impl Ctx {
266 let start = self.next_variant_idx(); 268 let start = self.next_variant_idx();
267 for variant in variants.variants() { 269 for variant in variants.variants() {
268 if let Some(data) = self.lower_variant(&variant) { 270 if let Some(data) = self.lower_variant(&variant) {
269 self.data().variants.alloc(data); 271 let idx = self.data().variants.alloc(data);
272 self.add_attrs(idx.into(), Attrs::new(&variant, &self.hygiene));
270 } 273 }
271 } 274 }
272 let end = self.next_variant_idx(); 275 let end = self.next_variant_idx();
@@ -419,7 +422,7 @@ impl Ctx {
419 let attrs = Attrs::new(&item, &this.hygiene); 422 let attrs = Attrs::new(&item, &this.hygiene);
420 this.collect_inner_items(item.syntax()); 423 this.collect_inner_items(item.syntax());
421 this.lower_assoc_item(&item).map(|item| { 424 this.lower_assoc_item(&item).map(|item| {
422 this.add_attrs(item.into(), attrs); 425 this.add_attrs(ModItem::from(item).into(), attrs);
423 item 426 item
424 }) 427 })
425 }) 428 })
@@ -453,7 +456,7 @@ impl Ctx {
453 self.collect_inner_items(item.syntax()); 456 self.collect_inner_items(item.syntax());
454 let assoc = self.lower_assoc_item(&item)?; 457 let assoc = self.lower_assoc_item(&item)?;
455 let attrs = Attrs::new(&item, &self.hygiene); 458 let attrs = Attrs::new(&item, &self.hygiene);
456 self.add_attrs(assoc.into(), attrs); 459 self.add_attrs(ModItem::from(assoc).into(), attrs);
457 Some(assoc) 460 Some(assoc)
458 }) 461 })
459 .collect(); 462 .collect();
@@ -539,7 +542,7 @@ impl Ctx {
539 .filter_map(|item| { 542 .filter_map(|item| {
540 self.collect_inner_items(item.syntax()); 543 self.collect_inner_items(item.syntax());
541 let attrs = Attrs::new(&item, &self.hygiene); 544 let attrs = Attrs::new(&item, &self.hygiene);
542 let id = match item { 545 let id: ModItem = match item {
543 ast::ExternItem::FnDef(ast) => { 546 ast::ExternItem::FnDef(ast) => {
544 let func = self.lower_function(&ast)?; 547 let func = self.lower_function(&ast)?;
545 func.into() 548 func.into()
@@ -549,7 +552,7 @@ impl Ctx {
549 statik.into() 552 statik.into()
550 } 553 }
551 }; 554 };
552 self.add_attrs(id, attrs); 555 self.add_attrs(id.into(), attrs);
553 Some(id) 556 Some(id)
554 }) 557 })
555 .collect() 558 .collect()
diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs
index fd7ffee24..18df42050 100644
--- a/crates/ra_hir_def/src/item_tree/tests.rs
+++ b/crates/ra_hir_def/src/item_tree/tests.rs
@@ -92,7 +92,7 @@ fn print_item_tree(ra_fixture: &str) -> String {
92} 92}
93 93
94fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) { 94fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) {
95 let attrs = tree.attrs(item); 95 let attrs = tree.attrs(item.into());
96 if !attrs.is_empty() { 96 if !attrs.is_empty() {
97 format_to!(out, "#[{:?}]\n", attrs); 97 format_to!(out, "#[{:?}]\n", attrs);
98 } 98 }
diff --git a/crates/ra_hir_def/src/nameres/collector.rs b/crates/ra_hir_def/src/nameres/collector.rs
index 94da700ad..2ced4f66b 100644
--- a/crates/ra_hir_def/src/nameres/collector.rs
+++ b/crates/ra_hir_def/src/nameres/collector.rs
@@ -742,7 +742,7 @@ impl ModCollector<'_, '_> {
742 // `#[macro_use] extern crate` is hoisted to imports macros before collecting 742 // `#[macro_use] extern crate` is hoisted to imports macros before collecting
743 // any other items. 743 // any other items.
744 for item in items { 744 for item in items {
745 if self.is_cfg_enabled(self.item_tree.attrs(*item)) { 745 if self.is_cfg_enabled(self.item_tree.attrs((*item).into())) {
746 if let ModItem::ExternCrate(id) = item { 746 if let ModItem::ExternCrate(id) = item {
747 let import = self.item_tree[*id].clone(); 747 let import = self.item_tree[*id].clone();
748 if import.is_macro_use { 748 if import.is_macro_use {
@@ -753,7 +753,7 @@ impl ModCollector<'_, '_> {
753 } 753 }
754 754
755 for &item in items { 755 for &item in items {
756 let attrs = self.item_tree.attrs(item); 756 let attrs = self.item_tree.attrs(item.into());
757 if self.is_cfg_enabled(attrs) { 757 if self.is_cfg_enabled(attrs) {
758 let module = 758 let module =
759 ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id }; 759 ModuleId { krate: self.def_collector.def_map.krate, local_id: self.module_id };