aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_hir_def/src/item_tree/lower.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/ra_hir_def/src/item_tree/lower.rs')
-rw-r--r--crates/ra_hir_def/src/item_tree/lower.rs41
1 files changed, 26 insertions, 15 deletions
diff --git a/crates/ra_hir_def/src/item_tree/lower.rs b/crates/ra_hir_def/src/item_tree/lower.rs
index 3bb437e81..88530af74 100644
--- a/crates/ra_hir_def/src/item_tree/lower.rs
+++ b/crates/ra_hir_def/src/item_tree/lower.rs
@@ -12,7 +12,7 @@ use ra_syntax::{
12 SyntaxNode, 12 SyntaxNode,
13}; 13};
14use smallvec::SmallVec; 14use smallvec::SmallVec;
15use std::{mem, sync::Arc}; 15use std::{collections::hash_map::Entry, mem, sync::Arc};
16 16
17fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> { 17fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> {
18 FileItemTreeId { index, _p: PhantomData } 18 FileItemTreeId { index, _p: PhantomData }
@@ -116,13 +116,24 @@ impl Ctx {
116 116
117 if !attrs.is_empty() { 117 if !attrs.is_empty() {
118 for item in items.iter().flat_map(|items| &items.0) { 118 for item in items.iter().flat_map(|items| &items.0) {
119 self.tree.attrs.insert(*item, attrs.clone()); 119 self.add_attrs(*item, attrs.clone());
120 } 120 }
121 } 121 }
122 122
123 items 123 items
124 } 124 }
125 125
126 fn add_attrs(&mut self, item: ModItem, attrs: Attrs) {
127 match self.tree.attrs.entry(item) {
128 Entry::Occupied(mut entry) => {
129 *entry.get_mut() = entry.get().merge(attrs);
130 }
131 Entry::Vacant(entry) => {
132 entry.insert(attrs);
133 }
134 }
135 }
136
126 fn collect_inner_items(&mut self, container: &SyntaxNode) { 137 fn collect_inner_items(&mut self, container: &SyntaxNode) {
127 let forced_vis = self.forced_visibility.take(); 138 let forced_vis = self.forced_visibility.take();
128 let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default()); 139 let mut inner_items = mem::replace(&mut self.tree.inner_items, FxHashMap::default());
@@ -147,7 +158,6 @@ impl Ctx {
147 } 158 }
148 159
149 fn lower_struct(&mut self, strukt: &ast::StructDef) -> Option<FileItemTreeId<Struct>> { 160 fn lower_struct(&mut self, strukt: &ast::StructDef) -> Option<FileItemTreeId<Struct>> {
150 let attrs = self.lower_attrs(strukt);
151 let visibility = self.lower_visibility(strukt); 161 let visibility = self.lower_visibility(strukt);
152 let name = strukt.name()?.as_name(); 162 let name = strukt.name()?.as_name();
153 let generic_params = self.lower_generic_params(GenericsOwner::Struct, strukt); 163 let generic_params = self.lower_generic_params(GenericsOwner::Struct, strukt);
@@ -158,7 +168,7 @@ impl Ctx {
158 ast::StructKind::Tuple(_) => StructDefKind::Tuple, 168 ast::StructKind::Tuple(_) => StructDefKind::Tuple,
159 ast::StructKind::Unit => StructDefKind::Unit, 169 ast::StructKind::Unit => StructDefKind::Unit,
160 }; 170 };
161 let res = Struct { name, attrs, visibility, generic_params, fields, ast_id, kind }; 171 let res = Struct { name, visibility, generic_params, fields, ast_id, kind };
162 Some(id(self.tree.structs.alloc(res))) 172 Some(id(self.tree.structs.alloc(res)))
163 } 173 }
164 174
@@ -215,7 +225,6 @@ impl Ctx {
215 } 225 }
216 226
217 fn lower_union(&mut self, union: &ast::UnionDef) -> Option<FileItemTreeId<Union>> { 227 fn lower_union(&mut self, union: &ast::UnionDef) -> Option<FileItemTreeId<Union>> {
218 let attrs = self.lower_attrs(union);
219 let visibility = self.lower_visibility(union); 228 let visibility = self.lower_visibility(union);
220 let name = union.name()?.as_name(); 229 let name = union.name()?.as_name();
221 let generic_params = self.lower_generic_params(GenericsOwner::Union, union); 230 let generic_params = self.lower_generic_params(GenericsOwner::Union, union);
@@ -226,12 +235,11 @@ impl Ctx {
226 None => Fields::Record(self.next_field_idx()..self.next_field_idx()), 235 None => Fields::Record(self.next_field_idx()..self.next_field_idx()),
227 }; 236 };
228 let ast_id = self.source_ast_id_map.ast_id(union); 237 let ast_id = self.source_ast_id_map.ast_id(union);
229 let res = Union { name, attrs, visibility, generic_params, fields, ast_id }; 238 let res = Union { name, visibility, generic_params, fields, ast_id };
230 Some(id(self.tree.unions.alloc(res))) 239 Some(id(self.tree.unions.alloc(res)))
231 } 240 }
232 241
233 fn lower_enum(&mut self, enum_: &ast::EnumDef) -> Option<FileItemTreeId<Enum>> { 242 fn lower_enum(&mut self, enum_: &ast::EnumDef) -> Option<FileItemTreeId<Enum>> {
234 let attrs = self.lower_attrs(enum_);
235 let visibility = self.lower_visibility(enum_); 243 let visibility = self.lower_visibility(enum_);
236 let name = enum_.name()?.as_name(); 244 let name = enum_.name()?.as_name();
237 let generic_params = self.lower_generic_params(GenericsOwner::Enum, enum_); 245 let generic_params = self.lower_generic_params(GenericsOwner::Enum, enum_);
@@ -240,7 +248,7 @@ impl Ctx {
240 None => self.next_variant_idx()..self.next_variant_idx(), 248 None => self.next_variant_idx()..self.next_variant_idx(),
241 }; 249 };
242 let ast_id = self.source_ast_id_map.ast_id(enum_); 250 let ast_id = self.source_ast_id_map.ast_id(enum_);
243 let res = Enum { name, attrs, visibility, generic_params, variants, ast_id }; 251 let res = Enum { name, visibility, generic_params, variants, ast_id };
244 Some(id(self.tree.enums.alloc(res))) 252 Some(id(self.tree.enums.alloc(res)))
245 } 253 }
246 254
@@ -263,7 +271,6 @@ impl Ctx {
263 } 271 }
264 272
265 fn lower_function(&mut self, func: &ast::FnDef) -> Option<FileItemTreeId<Function>> { 273 fn lower_function(&mut self, func: &ast::FnDef) -> Option<FileItemTreeId<Function>> {
266 let attrs = self.lower_attrs(func);
267 let visibility = self.lower_visibility(func); 274 let visibility = self.lower_visibility(func);
268 let name = func.name()?.as_name(); 275 let name = func.name()?.as_name();
269 276
@@ -309,7 +316,6 @@ impl Ctx {
309 let ast_id = self.source_ast_id_map.ast_id(func); 316 let ast_id = self.source_ast_id_map.ast_id(func);
310 let mut res = Function { 317 let mut res = Function {
311 name, 318 name,
312 attrs,
313 visibility, 319 visibility,
314 generic_params: GenericParams::default(), 320 generic_params: GenericParams::default(),
315 has_self_param, 321 has_self_param,
@@ -390,9 +396,13 @@ impl Ctx {
390 let items = trait_def.item_list().map(|list| { 396 let items = trait_def.item_list().map(|list| {
391 self.with_inherited_visibility(visibility.clone(), |this| { 397 self.with_inherited_visibility(visibility.clone(), |this| {
392 list.items() 398 list.items()
393 .flat_map(|item| { 399 .filter_map(|item| {
400 let attrs = Attrs::new(&item, &this.hygiene);
394 this.collect_inner_items(item.syntax()); 401 this.collect_inner_items(item.syntax());
395 this.lower_assoc_item(&item) 402 this.lower_assoc_item(&item).map(|item| {
403 this.add_attrs(item.into(), attrs);
404 item
405 })
396 }) 406 })
397 .collect() 407 .collect()
398 }) 408 })
@@ -422,6 +432,8 @@ impl Ctx {
422 .filter_map(|item| { 432 .filter_map(|item| {
423 self.collect_inner_items(item.syntax()); 433 self.collect_inner_items(item.syntax());
424 let assoc = self.lower_assoc_item(&item)?; 434 let assoc = self.lower_assoc_item(&item)?;
435 let attrs = Attrs::new(&item, &self.hygiene);
436 self.add_attrs(assoc.into(), attrs);
425 Some(assoc) 437 Some(assoc)
426 }) 438 })
427 .collect(); 439 .collect();
@@ -506,6 +518,7 @@ impl Ctx {
506 list.extern_items() 518 list.extern_items()
507 .filter_map(|item| { 519 .filter_map(|item| {
508 self.collect_inner_items(item.syntax()); 520 self.collect_inner_items(item.syntax());
521 let attrs = Attrs::new(&item, &self.hygiene);
509 let id = match item { 522 let id = match item {
510 ast::ExternItem::FnDef(ast) => { 523 ast::ExternItem::FnDef(ast) => {
511 let func = self.lower_function(&ast)?; 524 let func = self.lower_function(&ast)?;
@@ -516,6 +529,7 @@ impl Ctx {
516 statik.into() 529 statik.into()
517 } 530 }
518 }; 531 };
532 self.add_attrs(id, attrs);
519 Some(id) 533 Some(id)
520 }) 534 })
521 .collect() 535 .collect()
@@ -576,9 +590,6 @@ impl Ctx {
576 } 590 }
577 } 591 }
578 592
579 fn lower_attrs(&self, item: &impl ast::AttrsOwner) -> Attrs {
580 Attrs::new(item, &self.hygiene)
581 }
582 fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility { 593 fn lower_visibility(&self, item: &impl ast::VisibilityOwner) -> RawVisibility {
583 if let Some(vis) = self.forced_visibility.as_ref() { 594 if let Some(vis) = self.forced_visibility.as_ref() {
584 vis.clone() 595 vis.clone()