diff options
Diffstat (limited to 'crates/libsyntax2')
-rw-r--r-- | crates/libsyntax2/src/ast/mod.rs | 47 | ||||
-rw-r--r-- | crates/libsyntax2/src/yellow/mod.rs | 2 | ||||
-rw-r--r-- | crates/libsyntax2/src/yellow/syntax.rs | 37 |
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 @@ | |||
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 | } |
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 | }; |
11 | pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError}; | 11 | pub use self::syntax::{SyntaxNode, SyntaxNodeRef, SyntaxError, SyntaxNodeChildren}; |
12 | pub(crate) use self::{ | 12 | pub(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 @@ | |||
1 | use std::{ | 1 | use std::{ |
2 | fmt, sync::Arc, | 2 | fmt, sync::Arc, |
3 | hash::{Hasher, Hash}, | 3 | hash::{Hasher, Hash}, |
4 | ops::Range, | ||
4 | }; | 5 | }; |
5 | 6 | ||
6 | use smol_str::SmolStr; | 7 | use 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)] | ||
191 | pub struct SyntaxNodeChildren<R: TreeRoot> { | ||
192 | parent: SyntaxNode<R>, | ||
193 | iter: Range<usize>, | ||
194 | } | ||
195 | |||
196 | impl<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 | |||
195 | fn has_short_text(kind: SyntaxKind) -> bool { | 210 | fn 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, |