aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2')
-rw-r--r--crates/libsyntax2/src/ast/mod.rs47
-rw-r--r--crates/libsyntax2/src/yellow/mod.rs2
-rw-r--r--crates/libsyntax2/src/yellow/syntax.rs37
3 files changed, 65 insertions, 21 deletions
diff --git a/crates/libsyntax2/src/ast/mod.rs b/crates/libsyntax2/src/ast/mod.rs
index 881f380f3..0b6868547 100644
--- a/crates/libsyntax2/src/ast/mod.rs
+++ b/crates/libsyntax2/src/ast/mod.rs
@@ -1,10 +1,13 @@
1mod generated; 1mod generated;
2 2
3use std::marker::PhantomData;
4
3use itertools::Itertools; 5use itertools::Itertools;
4use smol_str::SmolStr; 6use smol_str::SmolStr;
5 7
6use { 8use {
7 SyntaxNodeRef, SyntaxKind::*, 9 SyntaxNodeRef, SyntaxKind::*,
10 yellow::{RefRoot, SyntaxNodeChildren},
8}; 11};
9pub use self::generated::*; 12pub use self::generated::*;
10 13
@@ -33,8 +36,8 @@ pub trait ArgListOwner<'a>: AstNode<'a> {
33} 36}
34 37
35pub trait FnDefOwner<'a>: AstNode<'a> { 38pub trait FnDefOwner<'a>: AstNode<'a> {
36 fn functions(self) -> Box<Iterator<Item=FnDef<'a>> + 'a> { 39 fn functions(self) -> AstNodeChildren<'a, FnDef<'a>> {
37 Box::new(children(self)) 40 children(self)
38 } 41 }
39} 42}
40 43
@@ -49,8 +52,8 @@ pub trait TypeParamsOwner<'a>: AstNode<'a> {
49} 52}
50 53
51pub trait AttrsOwner<'a>: AstNode<'a> { 54pub trait AttrsOwner<'a>: AstNode<'a> {
52 fn attrs(self) -> Box<Iterator<Item=Attr<'a>> + 'a> { 55 fn attrs(self) -> AstNodeChildren<'a, Attr<'a>> {
53 Box::new(children(self)) 56 children(self)
54 } 57 }
55} 58}
56 59
@@ -155,7 +158,7 @@ impl<'a> IfExpr<'a> {
155 pub fn else_branch(self) -> Option<Block<'a>> { 158 pub fn else_branch(self) -> Option<Block<'a>> {
156 self.blocks().nth(1) 159 self.blocks().nth(1)
157 } 160 }
158 fn blocks(self) -> impl Iterator<Item=Block<'a>> { 161 fn blocks(self) -> AstNodeChildren<'a, Block<'a>> {
159 children(self) 162 children(self)
160 } 163 }
161} 164}
@@ -164,8 +167,34 @@ fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option<C> {
164 children(parent).next() 167 children(parent).next()
165} 168}
166 169
167fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> impl Iterator<Item=C> + 'a { 170fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstNodeChildren<'a, C> {
168 parent.syntax() 171 AstNodeChildren::new(parent.syntax())
169 .children() 172}
170 .filter_map(C::cast) 173
174
175#[derive(Debug)]
176pub struct AstNodeChildren<'a, N> {
177 inner: SyntaxNodeChildren<RefRoot<'a>>,
178 ph: PhantomData<N>,
179}
180
181impl<'a, N> AstNodeChildren<'a, N> {
182 fn new(parent: SyntaxNodeRef<'a>) -> Self {
183 AstNodeChildren {
184 inner: parent.children(),
185 ph: PhantomData,
186 }
187 }
188}
189
190impl<'a, N: AstNode<'a>> Iterator for AstNodeChildren<'a, N> {
191 type Item = N;
192 fn next(&mut self) -> Option<N> {
193 loop {
194 match N::cast(self.inner.next()?) {
195 Some(n) => return Some(n),
196 None => (),
197 }
198 }
199 }
171} 200}
diff --git a/crates/libsyntax2/src/yellow/mod.rs b/crates/libsyntax2/src/yellow/mod.rs
index 82eda79d6..0596e702f 100644
--- a/crates/libsyntax2/src/yellow/mod.rs
+++ b/crates/libsyntax2/src/yellow/mod.rs
@@ -8,7 +8,7 @@ use std::{
8 sync::Arc, 8 sync::Arc,
9 ptr, 9 ptr,
10}; 10};
11pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError}; 11pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren};
12pub(crate) use self::{ 12pub(crate) use self::{
13 builder::GreenBuilder, 13 builder::GreenBuilder,
14 green::GreenNode, 14 green::GreenNode,
diff --git a/crates/libsyntax2/src/yellow/syntax.rs b/crates/libsyntax2/src/yellow/syntax.rs
index 444dbeb30..1d99cab4a 100644
--- a/crates/libsyntax2/src/yellow/syntax.rs
+++ b/crates/libsyntax2/src/yellow/syntax.rs
@@ -1,6 +1,7 @@
1use std::{ 1use std::{
2 fmt, sync::Arc, 2 fmt, sync::Arc,
3 hash::{Hasher, Hash}, 3 hash::{Hasher, Hash},
4 ops::Range,
4}; 5};
5 6
6use smol_str::SmolStr; 7use smol_str::SmolStr;
@@ -93,17 +94,11 @@ impl<R: TreeRoot> SyntaxNode<R> {
93 SyntaxText::new(self.borrowed()) 94 SyntaxText::new(self.borrowed())
94 } 95 }
95 96
96 pub fn children(&self) -> impl Iterator<Item = SyntaxNode<R>> { 97 pub fn children(&self) -> SyntaxNodeChildren<R> {
97 let red = self.red; 98 SyntaxNodeChildren {
98 let n_children = self.red().n_children(); 99 parent: self.clone(),
99 let root = self.root.clone(); 100 iter: (0..self.red().n_children())
100 (0..n_children).map(move |i| { 101 }
101 let red = unsafe { red.get(root.syntax_root()) };
102 SyntaxNode {
103 root: root.clone(),
104 red: red.get_child(i).unwrap(),
105 }
106 })
107 } 102 }
108 103
109 pub fn parent(&self) -> Option<SyntaxNode<R>> { 104 pub fn parent(&self) -> Option<SyntaxNode<R>> {
@@ -192,6 +187,26 @@ impl<R: TreeRoot> fmt::Debug for SyntaxNode<R> {
192 } 187 }
193} 188}
194 189
190#[derive(Debug)]
191pub struct SyntaxNodeChildren<R: TreeRoot> {
192 parent: SyntaxNode<R>,
193 iter: Range<usize>,
194}
195
196impl<R: TreeRoot> Iterator for SyntaxNodeChildren<R> {
197 type Item = SyntaxNode<R>;
198
199 fn next(&mut self) -> Option<SyntaxNode<R>> {
200 self.iter.next().map(|i| {
201 let red = self.parent.red();
202 SyntaxNode {
203 root: self.parent.root.clone(),
204 red: red.get_child(i).unwrap(),
205 }
206 })
207 }
208}
209
195fn has_short_text(kind: SyntaxKind) -> bool { 210fn has_short_text(kind: SyntaxKind) -> bool {
196 match kind { 211 match kind {
197 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true, 212 IDENT | LIFETIME | INT_NUMBER | FLOAT_NUMBER => true,