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.rs52
-rw-r--r--crates/libsyntax2/src/ast/mod.rs53
2 files changed, 79 insertions, 26 deletions
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<R: TreeRoot> AstNode<R> for ArrayType<R> {
23 23
24impl<R: TreeRoot> ArrayType<R> {} 24impl<R: TreeRoot> ArrayType<R> {}
25 25
26// Attr
27#[derive(Debug, Clone, Copy)]
28pub struct Attr<R: TreeRoot = Arc<SyntaxRoot>> {
29 syntax: SyntaxNode<R>,
30}
31
32impl<R: TreeRoot> AstNode<R> for Attr<R> {
33 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
34 match syntax.kind() {
35 ATTR => Some(Attr { syntax }),
36 _ => None,
37 }
38 }
39 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
40}
41
42impl<R: TreeRoot> Attr<R> {
43 pub fn value(&self) -> Option<TokenTree<R>> {
44 self.syntax()
45 .children()
46 .filter_map(TokenTree::cast)
47 .next()
48 }
49}
50
26// ConstDef 51// ConstDef
27#[derive(Debug, Clone, Copy)] 52#[derive(Debug, Clone, Copy)]
28pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> { 53pub struct ConstDef<R: TreeRoot = Arc<SyntaxRoot>> {
@@ -40,6 +65,7 @@ impl<R: TreeRoot> AstNode<R> for ConstDef<R> {
40} 65}
41 66
42impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {} 67impl<R: TreeRoot> ast::NameOwner<R> for ConstDef<R> {}
68impl<R: TreeRoot> ast::AttrsOwner<R> for ConstDef<R> {}
43impl<R: TreeRoot> ConstDef<R> {} 69impl<R: TreeRoot> ConstDef<R> {}
44 70
45// DynTraitType 71// DynTraitType
@@ -77,6 +103,7 @@ impl<R: TreeRoot> AstNode<R> for EnumDef<R> {
77} 103}
78 104
79impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {} 105impl<R: TreeRoot> ast::NameOwner<R> for EnumDef<R> {}
106impl<R: TreeRoot> ast::AttrsOwner<R> for EnumDef<R> {}
80impl<R: TreeRoot> EnumDef<R> {} 107impl<R: TreeRoot> EnumDef<R> {}
81 108
82// File 109// File
@@ -120,6 +147,7 @@ impl<R: TreeRoot> AstNode<R> for FnDef<R> {
120} 147}
121 148
122impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {} 149impl<R: TreeRoot> ast::NameOwner<R> for FnDef<R> {}
150impl<R: TreeRoot> ast::AttrsOwner<R> for FnDef<R> {}
123impl<R: TreeRoot> FnDef<R> {} 151impl<R: TreeRoot> FnDef<R> {}
124 152
125// FnPointerType 153// FnPointerType
@@ -211,6 +239,7 @@ impl<R: TreeRoot> AstNode<R> for Module<R> {
211} 239}
212 240
213impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {} 241impl<R: TreeRoot> ast::NameOwner<R> for Module<R> {}
242impl<R: TreeRoot> ast::AttrsOwner<R> for Module<R> {}
214impl<R: TreeRoot> Module<R> {} 243impl<R: TreeRoot> Module<R> {}
215 244
216// Name 245// Name
@@ -266,6 +295,7 @@ impl<R: TreeRoot> AstNode<R> for NamedField<R> {
266} 295}
267 296
268impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {} 297impl<R: TreeRoot> ast::NameOwner<R> for NamedField<R> {}
298impl<R: TreeRoot> ast::AttrsOwner<R> for NamedField<R> {}
269impl<R: TreeRoot> NamedField<R> {} 299impl<R: TreeRoot> NamedField<R> {}
270 300
271// NeverType 301// NeverType
@@ -436,6 +466,7 @@ impl<R: TreeRoot> AstNode<R> for StaticDef<R> {
436} 466}
437 467
438impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {} 468impl<R: TreeRoot> ast::NameOwner<R> for StaticDef<R> {}
469impl<R: TreeRoot> ast::AttrsOwner<R> for StaticDef<R> {}
439impl<R: TreeRoot> StaticDef<R> {} 470impl<R: TreeRoot> StaticDef<R> {}
440 471
441// StructDef 472// StructDef
@@ -455,6 +486,7 @@ impl<R: TreeRoot> AstNode<R> for StructDef<R> {
455} 486}
456 487
457impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {} 488impl<R: TreeRoot> ast::NameOwner<R> for StructDef<R> {}
489impl<R: TreeRoot> ast::AttrsOwner<R> for StructDef<R> {}
458impl<R: TreeRoot> StructDef<R> { 490impl<R: TreeRoot> StructDef<R> {
459 pub fn fields<'a>(&'a self) -> impl Iterator<Item = NamedField<R>> + 'a { 491 pub fn fields<'a>(&'a self) -> impl Iterator<Item = NamedField<R>> + 'a {
460 self.syntax() 492 self.syntax()
@@ -463,6 +495,24 @@ impl<R: TreeRoot> StructDef<R> {
463 } 495 }
464} 496}
465 497
498// TokenTree
499#[derive(Debug, Clone, Copy)]
500pub struct TokenTree<R: TreeRoot = Arc<SyntaxRoot>> {
501 syntax: SyntaxNode<R>,
502}
503
504impl<R: TreeRoot> AstNode<R> for TokenTree<R> {
505 fn cast(syntax: SyntaxNode<R>) -> Option<Self> {
506 match syntax.kind() {
507 TOKEN_TREE => Some(TokenTree { syntax }),
508 _ => None,
509 }
510 }
511 fn syntax(&self) -> &SyntaxNode<R> { &self.syntax }
512}
513
514impl<R: TreeRoot> TokenTree<R> {}
515
466// TraitDef 516// TraitDef
467#[derive(Debug, Clone, Copy)] 517#[derive(Debug, Clone, Copy)]
468pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> { 518pub struct TraitDef<R: TreeRoot = Arc<SyntaxRoot>> {
@@ -480,6 +530,7 @@ impl<R: TreeRoot> AstNode<R> for TraitDef<R> {
480} 530}
481 531
482impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {} 532impl<R: TreeRoot> ast::NameOwner<R> for TraitDef<R> {}
533impl<R: TreeRoot> ast::AttrsOwner<R> for TraitDef<R> {}
483impl<R: TreeRoot> TraitDef<R> {} 534impl<R: TreeRoot> TraitDef<R> {}
484 535
485// TupleType 536// TupleType
@@ -517,6 +568,7 @@ impl<R: TreeRoot> AstNode<R> for TypeDef<R> {
517} 568}
518 569
519impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {} 570impl<R: TreeRoot> ast::NameOwner<R> for TypeDef<R> {}
571impl<R: TreeRoot> ast::AttrsOwner<R> for TypeDef<R> {}
520impl<R: TreeRoot> TypeDef<R> {} 572impl<R: TreeRoot> TypeDef<R> {}
521 573
522// TypeRef 574// 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;
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