From 7094291573dc819e3115950ec3b2316bd5e9ea33 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Thu, 16 Aug 2018 12:51:40 +0300 Subject: tt-attrs --- crates/libsyntax2/src/ast/mod.rs | 53 ++++++++++++++++++++-------------------- 1 file changed, 27 insertions(+), 26 deletions(-) (limited to 'crates/libsyntax2/src/ast/mod.rs') diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs index 679e292a2..fe8f91d15 100644 --- a/crates/libsyntax2/src/ast/mod.rs +++ b/crates/libsyntax2/src/ast/mod.rs @@ -2,10 +2,11 @@ mod generated; use std::sync::Arc; +use itertools::Itertools; use smol_str::SmolStr; use { - SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, + SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError, SyntaxKind::*, }; pub use self::generated::*; @@ -14,6 +15,9 @@ pub trait AstNode { fn cast(syntax: SyntaxNode) -> Option where Self: Sized; fn syntax(&self) -> &SyntaxNode; + fn syntax_ref<'a>(&'a self) -> SyntaxNodeRef<'a> where R: 'a { + self.syntax().as_ref() + } } pub trait NameOwner: AstNode { @@ -25,6 +29,14 @@ pub trait NameOwner: AstNode { } } +pub trait AttrsOwner: AstNode { + fn attrs<'a>(&'a self) -> Box> + 'a> where R: 'a { + let it = self.syntax().children() + .filter_map(Attr::cast); + Box::new(it) + } +} + impl File> { pub fn parse(text: &str) -> Self { File::cast(::parse(text)).unwrap() @@ -39,31 +51,20 @@ impl File { impl FnDef { pub fn has_atom_attr(&self, atom: &str) -> bool { - self.syntax() - .children() - .filter(|node| node.kind() == ATTR) - .any(|attr| { - let mut metas = attr.children().filter(|node| node.kind() == META_ITEM); - let meta = match metas.next() { - None => return false, - Some(meta) => { - if metas.next().is_some() { - return false; - } - meta - } - }; - let mut children = meta.children(); - match children.next() { - None => false, - Some(child) => { - if children.next().is_some() { - return false; - } - child.kind() == IDENT && child.text() == atom - } - } - }) + self.attrs() + .filter_map(|x| x.value()) + .filter_map(|x| as_atom(x)) + .any(|x| x == atom) + } +} + +fn as_atom(tt: TokenTree) -> Option { + let syntax = tt.syntax_ref(); + let (_bra, attr, _ket) = syntax.children().collect_tuple()?; + if attr.kind() == IDENT { + Some(attr.leaf_text().unwrap()) + } else { + None } } -- cgit v1.2.3