diff options
Diffstat (limited to 'crates/libsyntax2/src/ast')
-rw-r--r-- | crates/libsyntax2/src/ast/mod.rs | 47 |
1 files changed, 38 insertions, 9 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 @@ | |||
1 | mod generated; | 1 | mod generated; |
2 | 2 | ||
3 | use std::marker::PhantomData; | ||
4 | |||
3 | use itertools::Itertools; | 5 | use itertools::Itertools; |
4 | use smol_str::SmolStr; | 6 | use smol_str::SmolStr; |
5 | 7 | ||
6 | use { | 8 | use { |
7 | SyntaxNodeRef, SyntaxKind::*, | 9 | SyntaxNodeRef, SyntaxKind::*, |
10 | yellow::{RefRoot, SyntaxNodeChildren}, | ||
8 | }; | 11 | }; |
9 | pub use self::generated::*; | 12 | pub use self::generated::*; |
10 | 13 | ||
@@ -33,8 +36,8 @@ pub trait ArgListOwner<'a>: AstNode<'a> { | |||
33 | } | 36 | } |
34 | 37 | ||
35 | pub trait FnDefOwner<'a>: AstNode<'a> { | 38 | pub 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 | ||
51 | pub trait AttrsOwner<'a>: AstNode<'a> { | 54 | pub 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 | ||
167 | fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> impl Iterator<Item=C> + 'a { | 170 | fn 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)] | ||
176 | pub struct AstNodeChildren<'a, N> { | ||
177 | inner: SyntaxNodeChildren<RefRoot<'a>>, | ||
178 | ph: PhantomData<N>, | ||
179 | } | ||
180 | |||
181 | impl<'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 | |||
190 | impl<'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 | } |