diff options
author | Jonas Schievink <[email protected]> | 2020-06-23 17:20:51 +0100 |
---|---|---|
committer | Jonas Schievink <[email protected]> | 2020-06-24 15:53:56 +0100 |
commit | ae7a296c85bba6ab279dd17b193f86db22ec3437 (patch) | |
tree | 42875a67886a80ca0ca3c4467cfea08ebe2f214f /crates/ra_hir_def | |
parent | 689e147c9dc416027fd36e94673431533df545f9 (diff) |
Unify and test attribute handling
Diffstat (limited to 'crates/ra_hir_def')
-rw-r--r-- | crates/ra_hir_def/src/attr.rs | 12 | ||||
-rw-r--r-- | crates/ra_hir_def/src/data.rs | 5 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree.rs | 4 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/lower.rs | 41 | ||||
-rw-r--r-- | crates/ra_hir_def/src/item_tree/tests.rs | 198 |
5 files changed, 227 insertions, 33 deletions
diff --git a/crates/ra_hir_def/src/attr.rs b/crates/ra_hir_def/src/attr.rs index deea83a6d..e0f468bf3 100644 --- a/crates/ra_hir_def/src/attr.rs +++ b/crates/ra_hir_def/src/attr.rs | |||
@@ -107,6 +107,18 @@ impl Attrs { | |||
107 | Attrs { entries } | 107 | Attrs { entries } |
108 | } | 108 | } |
109 | 109 | ||
110 | pub fn merge(&self, other: Attrs) -> Attrs { | ||
111 | match (&self.entries, &other.entries) { | ||
112 | (None, None) => Attrs { entries: None }, | ||
113 | (Some(entries), None) | (None, Some(entries)) => { | ||
114 | Attrs { entries: Some(entries.clone()) } | ||
115 | } | ||
116 | (Some(a), Some(b)) => { | ||
117 | Attrs { entries: Some(a.iter().chain(b.iter()).cloned().collect()) } | ||
118 | } | ||
119 | } | ||
120 | } | ||
121 | |||
110 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { | 122 | pub fn by_key(&self, key: &'static str) -> AttrQuery<'_> { |
111 | AttrQuery { attrs: self, key } | 123 | AttrQuery { attrs: self, key } |
112 | } | 124 | } |
diff --git a/crates/ra_hir_def/src/data.rs b/crates/ra_hir_def/src/data.rs index 921253c42..51c97c584 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.clone(), | 41 | params: func.params.clone(), |
42 | ret_type: func.ret_type.clone(), | 42 | ret_type: func.ret_type.clone(), |
43 | attrs: func.attrs.clone(), | 43 | attrs: item_tree.attrs(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: func.visibility.clone(), | 46 | visibility: func.visibility.clone(), |
@@ -224,7 +224,8 @@ 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 | if !item.attrs.is_cfg_enabled(&cfg_options) { | 227 | let attrs = item_tree.attrs(id.into()); |
228 | if !attrs.is_cfg_enabled(&cfg_options) { | ||
228 | continue; | 229 | continue; |
229 | } | 230 | } |
230 | let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); | 231 | let def = FunctionLoc { container, id: ItemTreeId::new(file_id, id) }.intern(db); |
diff --git a/crates/ra_hir_def/src/item_tree.rs b/crates/ra_hir_def/src/item_tree.rs index a1a78fc5c..6eb0c1b91 100644 --- a/crates/ra_hir_def/src/item_tree.rs +++ b/crates/ra_hir_def/src/item_tree.rs | |||
@@ -355,7 +355,6 @@ pub struct ExternCrate { | |||
355 | #[derive(Debug, Clone, Eq, PartialEq)] | 355 | #[derive(Debug, Clone, Eq, PartialEq)] |
356 | pub struct Function { | 356 | pub struct Function { |
357 | pub name: Name, | 357 | pub name: Name, |
358 | pub attrs: Attrs, | ||
359 | pub visibility: RawVisibility, | 358 | pub visibility: RawVisibility, |
360 | pub generic_params: GenericParams, | 359 | pub generic_params: GenericParams, |
361 | pub has_self_param: bool, | 360 | pub has_self_param: bool, |
@@ -368,7 +367,6 @@ pub struct Function { | |||
368 | #[derive(Debug, Clone, Eq, PartialEq)] | 367 | #[derive(Debug, Clone, Eq, PartialEq)] |
369 | pub struct Struct { | 368 | pub struct Struct { |
370 | pub name: Name, | 369 | pub name: Name, |
371 | pub attrs: Attrs, | ||
372 | pub visibility: RawVisibility, | 370 | pub visibility: RawVisibility, |
373 | pub generic_params: GenericParams, | 371 | pub generic_params: GenericParams, |
374 | pub fields: Fields, | 372 | pub fields: Fields, |
@@ -389,7 +387,6 @@ pub enum StructDefKind { | |||
389 | #[derive(Debug, Clone, Eq, PartialEq)] | 387 | #[derive(Debug, Clone, Eq, PartialEq)] |
390 | pub struct Union { | 388 | pub struct Union { |
391 | pub name: Name, | 389 | pub name: Name, |
392 | pub attrs: Attrs, | ||
393 | pub visibility: RawVisibility, | 390 | pub visibility: RawVisibility, |
394 | pub generic_params: GenericParams, | 391 | pub generic_params: GenericParams, |
395 | pub fields: Fields, | 392 | pub fields: Fields, |
@@ -399,7 +396,6 @@ pub struct Union { | |||
399 | #[derive(Debug, Clone, Eq, PartialEq)] | 396 | #[derive(Debug, Clone, Eq, PartialEq)] |
400 | pub struct Enum { | 397 | pub struct Enum { |
401 | pub name: Name, | 398 | pub name: Name, |
402 | pub attrs: Attrs, | ||
403 | pub visibility: RawVisibility, | 399 | pub visibility: RawVisibility, |
404 | pub generic_params: GenericParams, | 400 | pub generic_params: GenericParams, |
405 | pub variants: Range<Idx<Variant>>, | 401 | pub variants: Range<Idx<Variant>>, |
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 | }; |
14 | use smallvec::SmallVec; | 14 | use smallvec::SmallVec; |
15 | use std::{mem, sync::Arc}; | 15 | use std::{collections::hash_map::Entry, mem, sync::Arc}; |
16 | 16 | ||
17 | fn id<N: ItemTreeNode>(index: Idx<N>) -> FileItemTreeId<N> { | 17 | fn 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() |
diff --git a/crates/ra_hir_def/src/item_tree/tests.rs b/crates/ra_hir_def/src/item_tree/tests.rs index 7b8523b9f..2df1b3e0c 100644 --- a/crates/ra_hir_def/src/item_tree/tests.rs +++ b/crates/ra_hir_def/src/item_tree/tests.rs | |||
@@ -77,13 +77,12 @@ fn print_item_tree(ra_fixture: &str) -> String { | |||
77 | } | 77 | } |
78 | 78 | ||
79 | if !tree.inner_items.is_empty() { | 79 | if !tree.inner_items.is_empty() { |
80 | format_to!(out, "\ninner items:\n"); | 80 | format_to!(out, "\ninner items:\n\n"); |
81 | for (ast_id, items) in &tree.inner_items { | 81 | for (ast_id, items) in &tree.inner_items { |
82 | format_to!(out, "{:?}:\n", ast_id); | 82 | format_to!(out, "for AST {:?}:\n", ast_id); |
83 | for inner in items { | 83 | for inner in items { |
84 | format_to!(out, "- "); | ||
85 | fmt_mod_item(&mut out, &tree, *inner); | 84 | fmt_mod_item(&mut out, &tree, *inner); |
86 | format_to!(out, "\n"); | 85 | format_to!(out, "\n\n"); |
87 | } | 86 | } |
88 | } | 87 | } |
89 | } | 88 | } |
@@ -92,6 +91,12 @@ fn print_item_tree(ra_fixture: &str) -> String { | |||
92 | } | 91 | } |
93 | 92 | ||
94 | fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) { | 93 | fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) { |
94 | let attrs = tree.attrs(item); | ||
95 | if !attrs.is_empty() { | ||
96 | format_to!(out, "#[{:?}]\n", attrs); | ||
97 | } | ||
98 | |||
99 | let mut children = String::new(); | ||
95 | match item { | 100 | match item { |
96 | ModItem::ExternCrate(it) => { | 101 | ModItem::ExternCrate(it) => { |
97 | format_to!(out, "{:?}", tree[it]); | 102 | format_to!(out, "{:?}", tree[it]); |
@@ -119,20 +124,41 @@ fn fmt_mod_item(out: &mut String, tree: &ItemTree, item: ModItem) { | |||
119 | } | 124 | } |
120 | ModItem::Trait(it) => { | 125 | ModItem::Trait(it) => { |
121 | format_to!(out, "{:?}", tree[it]); | 126 | format_to!(out, "{:?}", tree[it]); |
127 | for item in &tree[it].items { | ||
128 | fmt_mod_item(&mut children, tree, ModItem::from(*item)); | ||
129 | format_to!(children, "\n"); | ||
130 | } | ||
122 | } | 131 | } |
123 | ModItem::Impl(it) => { | 132 | ModItem::Impl(it) => { |
124 | format_to!(out, "{:?}", tree[it]); | 133 | format_to!(out, "{:?}", tree[it]); |
134 | for item in &tree[it].items { | ||
135 | fmt_mod_item(&mut children, tree, ModItem::from(*item)); | ||
136 | format_to!(children, "\n"); | ||
137 | } | ||
125 | } | 138 | } |
126 | ModItem::TypeAlias(it) => { | 139 | ModItem::TypeAlias(it) => { |
127 | format_to!(out, "{:?}", tree[it]); | 140 | format_to!(out, "{:?}", tree[it]); |
128 | } | 141 | } |
129 | ModItem::Mod(it) => { | 142 | ModItem::Mod(it) => { |
130 | format_to!(out, "{:?}", tree[it]); | 143 | format_to!(out, "{:?}", tree[it]); |
144 | match &tree[it].kind { | ||
145 | ModKind::Inline { items } => { | ||
146 | for item in items { | ||
147 | fmt_mod_item(&mut children, tree, *item); | ||
148 | format_to!(children, "\n"); | ||
149 | } | ||
150 | } | ||
151 | ModKind::Outline {} => {} | ||
152 | } | ||
131 | } | 153 | } |
132 | ModItem::MacroCall(it) => { | 154 | ModItem::MacroCall(it) => { |
133 | format_to!(out, "{:?}", tree[it]); | 155 | format_to!(out, "{:?}", tree[it]); |
134 | } | 156 | } |
135 | } | 157 | } |
158 | |||
159 | for line in children.lines() { | ||
160 | format_to!(out, "\n> {}", line); | ||
161 | } | ||
136 | } | 162 | } |
137 | 163 | ||
138 | #[test] | 164 | #[test] |
@@ -140,44 +166,83 @@ fn smoke() { | |||
140 | assert_snapshot!(print_item_tree(r" | 166 | assert_snapshot!(print_item_tree(r" |
141 | #![attr] | 167 | #![attr] |
142 | 168 | ||
169 | #[attr_on_use] | ||
143 | use {a, b::*}; | 170 | use {a, b::*}; |
171 | |||
172 | #[ext_crate] | ||
144 | extern crate krate; | 173 | extern crate krate; |
145 | 174 | ||
175 | #[on_trait] | ||
146 | trait Tr<U> { | 176 | trait Tr<U> { |
177 | #[assoc_ty] | ||
147 | type AssocTy: Tr<()>; | 178 | type AssocTy: Tr<()>; |
179 | |||
180 | #[assoc_const] | ||
148 | const CONST: u8; | 181 | const CONST: u8; |
182 | |||
183 | #[assoc_method] | ||
149 | fn method(&self); | 184 | fn method(&self); |
185 | |||
186 | #[assoc_dfl_method] | ||
150 | fn dfl_method(&mut self) {} | 187 | fn dfl_method(&mut self) {} |
151 | } | 188 | } |
152 | 189 | ||
190 | #[struct0] | ||
153 | struct Struct0<T = ()>; | 191 | struct Struct0<T = ()>; |
154 | struct Struct1<T>(u8); | 192 | |
193 | #[struct1] | ||
194 | struct Struct1<T>(#[struct1fld] u8); | ||
195 | |||
196 | #[struct2] | ||
155 | struct Struct2<T> { | 197 | struct Struct2<T> { |
198 | #[struct2fld] | ||
156 | fld: (T, ), | 199 | fld: (T, ), |
157 | } | 200 | } |
158 | 201 | ||
202 | #[en] | ||
159 | enum En { | 203 | enum En { |
204 | #[enum_variant] | ||
160 | Variant { | 205 | Variant { |
206 | #[enum_field] | ||
161 | field: u8, | 207 | field: u8, |
162 | }, | 208 | }, |
163 | } | 209 | } |
164 | 210 | ||
211 | #[un] | ||
165 | union Un { | 212 | union Un { |
213 | #[union_fld] | ||
166 | fld: u16, | 214 | fld: u16, |
167 | } | 215 | } |
168 | "), @r###" | 216 | "), @r###" |
169 | inner attrs: Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr"))] }, input: None }]) } | 217 | inner attrs: Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr"))] }, input: None }]) } |
170 | 218 | ||
171 | top-level items: | 219 | top-level items: |
220 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }] | ||
172 | Import { path: ModPath { kind: Plain, segments: [Name(Text("a"))] }, alias: None, visibility: Module(ModPath { kind: Super(0), segments: [] }), is_glob: false, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) } | 221 | Import { path: ModPath { kind: Plain, segments: [Name(Text("a"))] }, alias: None, visibility: Module(ModPath { kind: Super(0), segments: [] }), is_glob: false, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) } |
222 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_on_use"))] }, input: None }]) }] | ||
173 | Import { path: ModPath { kind: Plain, segments: [Name(Text("b"))] }, alias: None, visibility: Module(ModPath { kind: Super(0), segments: [] }), is_glob: true, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) } | 223 | Import { path: ModPath { kind: Plain, segments: [Name(Text("b"))] }, alias: None, visibility: Module(ModPath { kind: Super(0), segments: [] }), is_glob: true, is_prelude: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UseItem>(0) } |
224 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("ext_crate"))] }, input: None }]) }] | ||
174 | ExternCrate { path: ModPath { kind: Plain, segments: [Name(Text("krate"))] }, alias: None, visibility: Module(ModPath { kind: Super(0), segments: [] }), is_macro_use: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ExternCrateItem>(1) } | 225 | ExternCrate { path: ModPath { kind: Plain, segments: [Name(Text("krate"))] }, alias: None, visibility: Module(ModPath { kind: Super(0), segments: [] }), is_macro_use: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ExternCrateItem>(1) } |
226 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_trait"))] }, input: None }]) }] | ||
175 | Trait { name: Name(Text("Tr")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 2, data: [TypeParamData { name: Some(Name(Text("Self"))), default: None, provenance: TraitSelf }, TypeParamData { name: Some(Name(Text("U"))), default: None, provenance: TypeParamList }] }, where_predicates: [] }, auto: false, items: [TypeAlias(Idx::<TypeAlias>(0)), Const(Idx::<Const>(0)), Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(2) } | 227 | Trait { name: Name(Text("Tr")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 2, data: [TypeParamData { name: Some(Name(Text("Self"))), default: None, provenance: TraitSelf }, TypeParamData { name: Some(Name(Text("U"))), default: None, provenance: TypeParamList }] }, where_predicates: [] }, auto: false, items: [TypeAlias(Idx::<TypeAlias>(0)), Const(Idx::<Const>(0)), Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(2) } |
176 | Struct { name: Name(Text("Struct0")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: Some(Tuple([])), provenance: TypeParamList }] }, where_predicates: [] }, fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit } | 228 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_ty"))] }, input: None }]) }] |
177 | Struct { name: Name(Text("Struct1")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [] }, fields: Tuple(Idx::<Field>(0)..Idx::<Field>(1)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(4), kind: Tuple } | 229 | > TypeAlias { name: Name(Text("AssocTy")), visibility: Module(ModPath { kind: Super(0), segments: [] }), bounds: [Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Tr"))] }, generic_args: [Some(GenericArgs { args: [Type(Tuple([]))], has_self_type: false, bindings: [] })] })], generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, type_ref: None, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TypeAliasDef>(8) } |
178 | Struct { name: Name(Text("Struct2")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [] }, fields: Record(Idx::<Field>(1)..Idx::<Field>(2)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(5), kind: Record } | 230 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_const"))] }, input: None }]) }] |
179 | Enum { name: Name(Text("En")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, variants: Idx::<Variant>(0)..Idx::<Variant>(1), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::EnumDef>(6) } | 231 | > Const { name: Some(Name(Text("CONST"))), visibility: Module(ModPath { kind: Super(0), segments: [] }), type_ref: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("u8"))] }, generic_args: [None] }), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ConstDef>(9) } |
180 | Union { name: Name(Text("Un")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, fields: Record(Idx::<Field>(3)..Idx::<Field>(4)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UnionDef>(7) } | 232 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_method"))] }, input: None }]) }] |
233 | > Function { name: Name(Text("method")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Shared)], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(10) } | ||
234 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("assoc_dfl_method"))] }, input: None }]) }] | ||
235 | > Function { name: Name(Text("dfl_method")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: true, is_unsafe: false, params: [Reference(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Self"))] }, generic_args: [None] }), Mut)], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(11) } | ||
236 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct0"))] }, input: None }]) }] | ||
237 | Struct { name: Name(Text("Struct0")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: Some(Tuple([])), provenance: TypeParamList }] }, where_predicates: [] }, fields: Unit, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(3), kind: Unit } | ||
238 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct1"))] }, input: None }]) }] | ||
239 | Struct { name: Name(Text("Struct1")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [] }, fields: Tuple(Idx::<Field>(0)..Idx::<Field>(1)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(4), kind: Tuple } | ||
240 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("struct2"))] }, input: None }]) }] | ||
241 | Struct { name: Name(Text("Struct2")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [] }, fields: Record(Idx::<Field>(1)..Idx::<Field>(2)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::StructDef>(5), kind: Record } | ||
242 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("en"))] }, input: None }]) }] | ||
243 | Enum { name: Name(Text("En")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, variants: Idx::<Variant>(0)..Idx::<Variant>(1), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::EnumDef>(6) } | ||
244 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("un"))] }, input: None }]) }] | ||
245 | Union { name: Name(Text("Un")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, fields: Record(Idx::<Field>(3)..Idx::<Field>(4)), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::UnionDef>(7) } | ||
181 | "###); | 246 | "###); |
182 | } | 247 | } |
183 | 248 | ||
@@ -201,10 +266,92 @@ inner attrs: Attrs { entries: None } | |||
201 | 266 | ||
202 | top-level items: | 267 | top-level items: |
203 | Impl { generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("A"))] }, generic_args: [None] }) }] }, target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } | 268 | Impl { generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("T"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("A"))] }, generic_args: [None] }) }] }, target_trait: Some(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("D"))] }, generic_args: [None] })), target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Response"))] }, generic_args: [Some(GenericArgs { args: [Type(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("T"))] }, generic_args: [None] }))], has_self_type: false, bindings: [] })] }), is_negative: false, items: [Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } |
269 | > Function { name: Name(Text("foo")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | ||
204 | 270 | ||
205 | inner items: | 271 | inner items: |
206 | FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): | 272 | |
207 | - Function { name: Name(Text("end")), attrs: Attrs { entries: None }, visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("W"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("W"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Write"))] }, generic_args: [None] }) }] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | 273 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(2): |
274 | Function { name: Name(Text("end")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("W"))), default: None, provenance: TypeParamList }] }, where_predicates: [WherePredicate { target: TypeRef(Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("W"))] }, generic_args: [None] })), bound: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Write"))] }, generic_args: [None] }) }] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | ||
275 | |||
276 | "###); | ||
277 | } | ||
278 | |||
279 | #[test] | ||
280 | fn extern_attrs() { | ||
281 | let tree = print_item_tree( | ||
282 | r#" | ||
283 | #[block_attr] | ||
284 | extern "C" { | ||
285 | #[attr_a] | ||
286 | fn a() {} | ||
287 | #[attr_b] | ||
288 | fn b() {} | ||
289 | } | ||
290 | "#, | ||
291 | ); | ||
292 | |||
293 | assert_snapshot!(tree, @r###" | ||
294 | inner attrs: Attrs { entries: None } | ||
295 | |||
296 | top-level items: | ||
297 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }] | ||
298 | Function { name: Name(Text("a")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | ||
299 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }, Attr { path: ModPath { kind: Plain, segments: [Name(Text("block_attr"))] }, input: None }]) }] | ||
300 | Function { name: Name(Text("b")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | ||
301 | "###); | ||
302 | } | ||
303 | |||
304 | #[test] | ||
305 | fn trait_attrs() { | ||
306 | let tree = print_item_tree( | ||
307 | r#" | ||
308 | #[trait_attr] | ||
309 | trait Tr { | ||
310 | #[attr_a] | ||
311 | fn a() {} | ||
312 | #[attr_b] | ||
313 | fn b() {} | ||
314 | } | ||
315 | "#, | ||
316 | ); | ||
317 | |||
318 | assert_snapshot!(tree, @r###" | ||
319 | inner attrs: Attrs { entries: None } | ||
320 | |||
321 | top-level items: | ||
322 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("trait_attr"))] }, input: None }]) }] | ||
323 | Trait { name: Name(Text("Tr")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 1, data: [TypeParamData { name: Some(Name(Text("Self"))), default: None, provenance: TraitSelf }] }, where_predicates: [] }, auto: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::TraitDef>(0) } | ||
324 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }] | ||
325 | > Function { name: Name(Text("a")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | ||
326 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }] | ||
327 | > Function { name: Name(Text("b")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | ||
328 | "###); | ||
329 | } | ||
330 | |||
331 | #[test] | ||
332 | fn impl_attrs() { | ||
333 | let tree = print_item_tree( | ||
334 | r#" | ||
335 | #[impl_attr] | ||
336 | impl Ty { | ||
337 | #[attr_a] | ||
338 | fn a() {} | ||
339 | #[attr_b] | ||
340 | fn b() {} | ||
341 | } | ||
342 | "#, | ||
343 | ); | ||
344 | |||
345 | assert_snapshot!(tree, @r###" | ||
346 | inner attrs: Attrs { entries: None } | ||
347 | |||
348 | top-level items: | ||
349 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("impl_attr"))] }, input: None }]) }] | ||
350 | Impl { generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("Ty"))] }, generic_args: [None] }), is_negative: false, items: [Function(Idx::<Function>(0)), Function(Idx::<Function>(1))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } | ||
351 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_a"))] }, input: None }]) }] | ||
352 | > Function { name: Name(Text("a")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | ||
353 | > #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("attr_b"))] }, input: None }]) }] | ||
354 | > Function { name: Name(Text("b")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(2) } | ||
208 | "###); | 355 | "###); |
209 | } | 356 | } |
210 | 357 | ||
@@ -236,6 +383,32 @@ fn cursed_inner_items() { | |||
236 | } | 383 | } |
237 | 384 | ||
238 | #[test] | 385 | #[test] |
386 | fn inner_item_attrs() { | ||
387 | let tree = print_item_tree( | ||
388 | r" | ||
389 | fn foo() { | ||
390 | #[on_inner] | ||
391 | fn inner() {} | ||
392 | } | ||
393 | ", | ||
394 | ); | ||
395 | |||
396 | assert_snapshot!(tree, @r###" | ||
397 | inner attrs: Attrs { entries: None } | ||
398 | |||
399 | top-level items: | ||
400 | Function { name: Name(Text("foo")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(0) } | ||
401 | |||
402 | inner items: | ||
403 | |||
404 | for AST FileAstId::<ra_syntax::ast::generated::nodes::ModuleItem>(1): | ||
405 | #[Attrs { entries: Some([Attr { path: ModPath { kind: Plain, segments: [Name(Text("on_inner"))] }, input: None }]) }] | ||
406 | Function { name: Name(Text("inner")), visibility: Module(ModPath { kind: Super(0), segments: [] }), generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, has_self_param: false, is_unsafe: false, params: [], ret_type: Tuple([]), ast_id: FileAstId::<ra_syntax::ast::generated::nodes::FnDef>(1) } | ||
407 | |||
408 | "###); | ||
409 | } | ||
410 | |||
411 | #[test] | ||
239 | fn assoc_item_macros() { | 412 | fn assoc_item_macros() { |
240 | let tree = print_item_tree( | 413 | let tree = print_item_tree( |
241 | r" | 414 | r" |
@@ -250,5 +423,6 @@ inner attrs: Attrs { entries: None } | |||
250 | 423 | ||
251 | top-level items: | 424 | top-level items: |
252 | Impl { generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("S"))] }, generic_args: [None] }), is_negative: false, items: [MacroCall(Idx::<MacroCall>(0))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } | 425 | Impl { generic_params: GenericParams { types: Arena { len: 0, data: [] }, where_predicates: [] }, target_trait: None, target_type: Path(Path { type_anchor: None, mod_path: ModPath { kind: Plain, segments: [Name(Text("S"))] }, generic_args: [None] }), is_negative: false, items: [MacroCall(Idx::<MacroCall>(0))], ast_id: FileAstId::<ra_syntax::ast::generated::nodes::ImplDef>(0) } |
426 | > MacroCall { name: None, path: ModPath { kind: Plain, segments: [Name(Text("items"))] }, is_export: false, is_local_inner: false, is_builtin: false, ast_id: FileAstId::<ra_syntax::ast::generated::nodes::MacroCall>(1) } | ||
253 | "###); | 427 | "###); |
254 | } | 428 | } |