aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/ast/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/ast/mod.rs')
-rw-r--r--crates/libsyntax2/src/ast/mod.rs53
1 files changed, 27 insertions, 26 deletions
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;
2 2
3use std::sync::Arc; 3use std::sync::Arc;
4 4
5use itertools::Itertools;
5use smol_str::SmolStr; 6use smol_str::SmolStr;
6 7
7use { 8use {
8 SyntaxNode, SyntaxRoot, TreeRoot, SyntaxError, 9 SyntaxNode, SyntaxNodeRef, SyntaxRoot, TreeRoot, SyntaxError,
9 SyntaxKind::*, 10 SyntaxKind::*,
10}; 11};
11pub use self::generated::*; 12pub use self::generated::*;
@@ -14,6 +15,9 @@ pub trait AstNode<R: TreeRoot> {
14 fn cast(syntax: SyntaxNode<R>) -> Option<Self> 15 fn cast(syntax: SyntaxNode<R>) -> Option<Self>
15 where Self: Sized; 16 where Self: Sized;
16 fn syntax(&self) -> &SyntaxNode<R>; 17 fn syntax(&self) -> &SyntaxNode<R>;
18 fn syntax_ref<'a>(&'a self) -> SyntaxNodeRef<'a> where R: 'a {
19 self.syntax().as_ref()
20 }
17} 21}
18 22
19pub trait NameOwner<R: TreeRoot>: AstNode<R> { 23pub trait NameOwner<R: TreeRoot>: AstNode<R> {
@@ -25,6 +29,14 @@ pub trait NameOwner<R: TreeRoot>: AstNode<R> {
25 } 29 }
26} 30}
27 31
32pub trait AttrsOwner<R: TreeRoot>: AstNode<R> {
33 fn attrs<'a>(&'a self) -> Box<Iterator<Item=Attr<R>> + 'a> where R: 'a {
34 let it = self.syntax().children()
35 .filter_map(Attr::cast);
36 Box::new(it)
37 }
38}
39
28impl File<Arc<SyntaxRoot>> { 40impl File<Arc<SyntaxRoot>> {
29 pub fn parse(text: &str) -> Self { 41 pub fn parse(text: &str) -> Self {
30 File::cast(::parse(text)).unwrap() 42 File::cast(::parse(text)).unwrap()
@@ -39,31 +51,20 @@ impl<R: TreeRoot> File<R> {
39 51
40impl<R: TreeRoot> FnDef<R> { 52impl<R: TreeRoot> FnDef<R> {
41 pub fn has_atom_attr(&self, atom: &str) -> bool { 53 pub fn has_atom_attr(&self, atom: &str) -> bool {
42 self.syntax() 54 self.attrs()
43 .children() 55 .filter_map(|x| x.value())
44 .filter(|node| node.kind() == ATTR) 56 .filter_map(|x| as_atom(x))
45 .any(|attr| { 57 .any(|x| x == atom)
46 let mut metas = attr.children().filter(|node| node.kind() == META_ITEM); 58 }
47 let meta = match metas.next() { 59}
48 None => return false, 60
49 Some(meta) => { 61fn as_atom<R: TreeRoot>(tt: TokenTree<R>) -> Option<SmolStr> {
50 if metas.next().is_some() { 62 let syntax = tt.syntax_ref();
51 return false; 63 let (_bra, attr, _ket) = syntax.children().collect_tuple()?;
52 } 64 if attr.kind() == IDENT {
53 meta 65 Some(attr.leaf_text().unwrap())
54 } 66 } else {
55 }; 67 None
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 }
68} 69}
69 70