Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/syntax/src/ast/traits.rs')
| -rw-r--r-- | crates/syntax/src/ast/traits.rs | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/crates/syntax/src/ast/traits.rs b/crates/syntax/src/ast/traits.rs index 152b0cb98c..5d6aa4331b 100644 --- a/crates/syntax/src/ast/traits.rs +++ b/crates/syntax/src/ast/traits.rs @@ -75,6 +75,33 @@ pub trait HasAttrs: AstNode { fn has_atom_attr(&self, atom: &str) -> bool { self.attrs().filter_map(|x| x.as_simple_atom()).any(|x| x == atom) } + + /// Returns all attributes of this node, including inner attributes that may not be directly under this node + /// but under a child. + fn attrs_including_inner(self) -> impl Iterator<Item = ast::Attr> + where + Self: Sized, + { + let inner_attrs_node = if let Some(it) = + support::child::<ast::BlockExpr>(self.syntax()).and_then(|it| it.stmt_list()) + { + Some(it.syntax) + } else if let Some(it) = support::child::<ast::MatchArmList>(self.syntax()) { + Some(it.syntax) + } else if let Some(it) = support::child::<ast::AssocItemList>(self.syntax()) { + Some(it.syntax) + } else if let Some(it) = support::child::<ast::ItemList>(self.syntax()) { + Some(it.syntax) + } else if let Some(it) = support::child::<ast::ExternItemList>(self.syntax()) { + Some(it.syntax) + } else if let Some(it) = support::child::<ast::MacroItems>(self.syntax()) { + Some(it.syntax) + } else { + None + }; + + self.attrs().chain(inner_attrs_node.into_iter().flat_map(|it| support::children(&it))) + } } pub trait HasDocComments: HasAttrs { |