From 7c67612b8a894187fa3b64725531a5459f9211bf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 10 Aug 2018 22:33:29 +0300 Subject: organizize --- crates/libsyntax2/src/ast/generated.rs | 54 +++++++++++++++++++++ crates/libsyntax2/src/ast/generated.rs.tera | 22 +++++++++ crates/libsyntax2/src/ast/mod.rs | 74 +++++++++++++++++++++++++++++ 3 files changed, 150 insertions(+) create mode 100644 crates/libsyntax2/src/ast/generated.rs create mode 100644 crates/libsyntax2/src/ast/generated.rs.tera create mode 100644 crates/libsyntax2/src/ast/mod.rs (limited to 'crates/libsyntax2/src/ast') diff --git a/crates/libsyntax2/src/ast/generated.rs b/crates/libsyntax2/src/ast/generated.rs new file mode 100644 index 000000000..2f813050a --- /dev/null +++ b/crates/libsyntax2/src/ast/generated.rs @@ -0,0 +1,54 @@ +use std::sync::Arc; +use { + SyntaxNode, SyntaxRoot, TreeRoot, AstNode, + SyntaxKind::*, +}; + + +#[derive(Debug, Clone, Copy)] +pub struct File> { + syntax: SyntaxNode, +} + +impl AstNode for File { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + FILE => Some(File { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + + +#[derive(Debug, Clone, Copy)] +pub struct Function> { + syntax: SyntaxNode, +} + +impl AstNode for Function { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + FUNCTION => Some(Function { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + + +#[derive(Debug, Clone, Copy)] +pub struct Name> { + syntax: SyntaxNode, +} + +impl AstNode for Name { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + NAME => Some(Name { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} + diff --git a/crates/libsyntax2/src/ast/generated.rs.tera b/crates/libsyntax2/src/ast/generated.rs.tera new file mode 100644 index 000000000..242837801 --- /dev/null +++ b/crates/libsyntax2/src/ast/generated.rs.tera @@ -0,0 +1,22 @@ +use std::sync::Arc; +use { + SyntaxNode, SyntaxRoot, TreeRoot, AstNode, + SyntaxKind::*, +}; +{% for node in ast %} +{% set Name = node.kind | camel %} +#[derive(Debug, Clone, Copy)] +pub struct {{ Name }}> { + syntax: SyntaxNode, +} + +impl AstNode for {{ Name }} { + fn cast(syntax: SyntaxNode) -> Option { + match syntax.kind() { + {{ node.kind }} => Some({{ Name }} { syntax }), + _ => None, + } + } + fn syntax(&self) -> &SyntaxNode { &self.syntax } +} +{% endfor %} diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs new file mode 100644 index 000000000..eeb7ae6f6 --- /dev/null +++ b/crates/libsyntax2/src/ast/mod.rs @@ -0,0 +1,74 @@ +mod generated; + +use std::sync::Arc; +use { + SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, + SyntaxKind::*, +}; +pub use self::generated::*; + +pub trait AstNode: Sized { + fn cast(syntax: SyntaxNode) -> Option; + fn syntax(&self) -> &SyntaxNode; +} + +impl File> { + pub fn parse(text: &str) -> Self { + File::cast(::parse(text)).unwrap() + } +} + +impl File { + pub fn errors(&self) -> Vec { + self.syntax().root.errors.clone() + } + + pub fn functions<'a>(&'a self) -> impl Iterator> + 'a { + self.syntax() + .children() + .filter_map(Function::cast) + } +} + +impl Function { + pub fn name(&self) -> Option> { + self.syntax() + .children() + .filter_map(Name::cast) + .next() + } + + 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 + } + } + }) + } +} + +impl Name { + pub fn text(&self) -> String { + self.syntax().text() + } +} -- cgit v1.2.3