aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/ast/mod.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-07 23:16:07 +0100
committerAleksey Kladov <[email protected]>2018-09-07 23:16:07 +0100
commitff1c82216cc05f2621a301e30ab7a1102dea9d2b (patch)
tree393fb79e9fb06afe26eddfa66a59113a10dba26c /crates/libsyntax2/src/ast/mod.rs
parentfcfda94664b454f60be2dbc1b564ed63aa4c3ec5 (diff)
Remove dyn dispatch
Diffstat (limited to 'crates/libsyntax2/src/ast/mod.rs')
-rw-r--r--crates/libsyntax2/src/ast/mod.rs47
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 @@
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}