From ff1c82216cc05f2621a301e30ab7a1102dea9d2b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 8 Sep 2018 01:16:07 +0300 Subject: Remove dyn dispatch --- crates/libsyntax2/src/ast/mod.rs | 47 ++++++++++++++++++++++++++++++++-------- 1 file changed, 38 insertions(+), 9 deletions(-) (limited to 'crates/libsyntax2/src/ast') 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 @@ mod generated; +use std::marker::PhantomData; + use itertools::Itertools; use smol_str::SmolStr; use { SyntaxNodeRef, SyntaxKind::*, + yellow::{RefRoot, SyntaxNodeChildren}, }; pub use self::generated::*; @@ -33,8 +36,8 @@ pub trait ArgListOwner<'a>: AstNode<'a> { } pub trait FnDefOwner<'a>: AstNode<'a> { - fn functions(self) -> Box> + 'a> { - Box::new(children(self)) + fn functions(self) -> AstNodeChildren<'a, FnDef<'a>> { + children(self) } } @@ -49,8 +52,8 @@ pub trait TypeParamsOwner<'a>: AstNode<'a> { } pub trait AttrsOwner<'a>: AstNode<'a> { - fn attrs(self) -> Box> + 'a> { - Box::new(children(self)) + fn attrs(self) -> AstNodeChildren<'a, Attr<'a>> { + children(self) } } @@ -155,7 +158,7 @@ impl<'a> IfExpr<'a> { pub fn else_branch(self) -> Option> { self.blocks().nth(1) } - fn blocks(self) -> impl Iterator> { + fn blocks(self) -> AstNodeChildren<'a, Block<'a>> { children(self) } } @@ -164,8 +167,34 @@ fn child_opt<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> Option { children(parent).next() } -fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> impl Iterator + 'a { - parent.syntax() - .children() - .filter_map(C::cast) +fn children<'a, P: AstNode<'a>, C: AstNode<'a>>(parent: P) -> AstNodeChildren<'a, C> { + AstNodeChildren::new(parent.syntax()) +} + + +#[derive(Debug)] +pub struct AstNodeChildren<'a, N> { + inner: SyntaxNodeChildren>, + ph: PhantomData, +} + +impl<'a, N> AstNodeChildren<'a, N> { + fn new(parent: SyntaxNodeRef<'a>) -> Self { + AstNodeChildren { + inner: parent.children(), + ph: PhantomData, + } + } +} + +impl<'a, N: AstNode<'a>> Iterator for AstNodeChildren<'a, N> { + type Item = N; + fn next(&mut self) -> Option { + loop { + match N::cast(self.inner.next()?) { + Some(n) => return Some(n), + None => (), + } + } + } } -- cgit v1.2.3