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/generated.rs | 52 +++++++++++++++++++++++++++++++++ crates/libsyntax2/src/ast/mod.rs | 53 +++++++++++++++++----------------- 2 files changed, 79 insertions(+), 26 deletions(-) (limited to 'crates/libsyntax2/src/ast') diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs index 1ec05c950..c575e15df 100644 --- a/crates/libsyntax2/src/ast/generated.rs +++ b/crates/libsyntax2/src/ast/generated.rs @@ -23,6 +23,31 @@ impl AstNode for ArrayType { impl ArrayType {} +// Attr +#[derive(Debug, Clone, Copy)] +pub struct Attr> { + syntax: SyntaxNode, +} + +impl AstNode for Attr { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + ATTR => Some(Attr { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl Attr { + pub fn value(&self) -> Option> { + self.syntax() + .children() + .filter_map(TokenTree::cast) + .next() + } +} + // ConstDef #[derive(Debug, Clone, Copy)] pub struct ConstDef> { @@ -40,6 +65,7 @@ impl AstNode for ConstDef { } impl ast::NameOwner for ConstDef {} +impl ast::AttrsOwner for ConstDef {} impl ConstDef {} // DynTraitType @@ -77,6 +103,7 @@ impl AstNode for EnumDef { } impl ast::NameOwner for EnumDef {} +impl ast::AttrsOwner for EnumDef {} impl EnumDef {} // File @@ -120,6 +147,7 @@ impl AstNode for FnDef { } impl ast::NameOwner for FnDef {} +impl ast::AttrsOwner for FnDef {} impl FnDef {} // FnPointerType @@ -211,6 +239,7 @@ impl AstNode for Module { } impl ast::NameOwner for Module {} +impl ast::AttrsOwner for Module {} impl Module {} // Name @@ -266,6 +295,7 @@ impl AstNode for NamedField { } impl ast::NameOwner for NamedField {} +impl ast::AttrsOwner for NamedField {} impl NamedField {} // NeverType @@ -436,6 +466,7 @@ impl AstNode for StaticDef { } impl ast::NameOwner for StaticDef {} +impl ast::AttrsOwner for StaticDef {} impl StaticDef {} // StructDef @@ -455,6 +486,7 @@ impl AstNode for StructDef { } impl ast::NameOwner for StructDef {} +impl ast::AttrsOwner for StructDef {} impl StructDef { pub fn fields<'a>(&'a self) -> impl Iterator> + 'a { self.syntax() @@ -463,6 +495,24 @@ impl StructDef { } } +// TokenTree +#[derive(Debug, Clone, Copy)] +pub struct TokenTree> { + syntax: SyntaxNode, +} + +impl AstNode for TokenTree { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + TOKEN_TREE => Some(TokenTree { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + +impl TokenTree {} + // TraitDef #[derive(Debug, Clone, Copy)] pub struct TraitDef> { @@ -480,6 +530,7 @@ impl AstNode for TraitDef { } impl ast::NameOwner for TraitDef {} +impl ast::AttrsOwner for TraitDef {} impl TraitDef {} // TupleType @@ -517,6 +568,7 @@ impl AstNode for TypeDef { } impl ast::NameOwner for TypeDef {} +impl ast::AttrsOwner for TypeDef {} impl TypeDef {} // TypeRef 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