aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/ast')
-rw-r--r--crates/libsyntax2/src/ast/generated.rs54
-rw-r--r--crates/libsyntax2/src/ast/generated.rs.tera22
-rw-r--r--crates/libsyntax2/src/ast/mod.rs74
3 files changed, 150 insertions, 0 deletions
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 @@
1use std::sync::Arc;
2use {
3 SyntaxNode, SyntaxRoot, TreeRoot, AstNode,
4 SyntaxKind::*,
5};
6
7
8#[derive(Debug, Clone, Copy)]
9pub struct File<R: TreeRoot = Arc<SyntaxRoot>> {
10 syntax: SyntaxNode<R>,
11}
12
13impl<R: TreeRoot> AstNode<R> for File<R> {
14 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
15 match syntax.kind() {
16 FILE => Some(File { syntax }),
17 _ => None,
18 }
19 }
20 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
21}
22
23
24#[derive(Debug, Clone, Copy)]
25pub struct Function<R: TreeRoot = Arc<SyntaxRoot>> {
26 syntax: SyntaxNode<R>,
27}
28
29impl<R: TreeRoot> AstNode<R> for Function<R> {
30 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
31 match syntax.kind() {
32 FUNCTION => Some(Function { syntax }),
33 _ => None,
34 }
35 }
36 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
37}
38
39
40#[derive(Debug, Clone, Copy)]
41pub struct Name<R: TreeRoot = Arc<SyntaxRoot>> {
42 syntax: SyntaxNode<R>,
43}
44
45impl<R: TreeRoot> AstNode<R> for Name<R> {
46 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
47 match syntax.kind() {
48 NAME => Some(Name { syntax }),
49 _ => None,
50 }
51 }
52 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
53}
54
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 @@
1use std::sync::Arc;
2use {
3 SyntaxNode, SyntaxRoot, TreeRoot, AstNode,
4 SyntaxKind::*,
5};
6{% for node in ast %}
7{% set Name = node.kind | camel %}
8#[derive(Debug, Clone, Copy)]
9pub struct {{ Name }}<R: TreeRoot = Arc<SyntaxRoot>> {
10 syntax: SyntaxNode<R>,
11}
12
13impl<R: TreeRoot> AstNode<R> for {{ Name }}<R> {
14 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
15 match syntax.kind() {
16 {{ node.kind }} => Some({{ Name }} { syntax }),
17 _ => None,
18 }
19 }
20 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
21}
22{% 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 @@
1mod generated;
2
3use std::sync::Arc;
4use {
5 SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError,
6 SyntaxKind::*,
7};
8pub use self::generated::*;
9
10pub trait AstNode<R: TreeRoot>: Sized {
11 fn cast(syntax: SyntaxNode<R>) -> Option<Self>;
12 fn syntax(&self) -> &SyntaxNode<R>;
13}
14
15impl File<Arc<SyntaxRoot>> {
16 pub fn parse(text: &str) -> Self {
17 File::cast(::parse(text)).unwrap()
18 }
19}
20
21impl<R: TreeRoot> File<R> {
22 pub fn errors(&self) -> Vec<SyntaxError> {
23 self.syntax().root.errors.clone()
24 }
25
26 pub fn functions<'a>(&'a self) -> impl Iterator<Item = Function<R>> + 'a {
27 self.syntax()
28 .children()
29 .filter_map(Function::cast)
30 }
31}
32
33impl<R: TreeRoot> Function<R> {
34 pub fn name(&self) -> Option<Name<R>> {
35 self.syntax()
36 .children()
37 .filter_map(Name::cast)
38 .next()
39 }
40
41 pub fn has_atom_attr(&self, atom: &str) -> bool {
42 self.syntax()
43 .children()
44 .filter(|node| node.kind() == ATTR)
45 .any(|attr| {
46 let mut metas = attr.children().filter(|node| node.kind() == META_ITEM);
47 let meta = match metas.next() {
48 None => return false,
49 Some(meta) => {
50 if metas.next().is_some() {
51 return false;
52 }
53 meta
54 }
55 };
56 let mut children = meta.children();
57 match children.next() {
58 None => false,
59 Some(child) => {
60 if children.next().is_some() {
61 return false;
62 }
63 child.kind() == IDENT && child.text() == atom
64 }
65 }
66 })
67 }
68}
69
70impl<R: TreeRoot> Name<R> {
71 pub fn text(&self) -> String {
72 self.syntax().text()
73 }
74}