aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-08-15 19:25:29 +0100
committerAleksey Kladov <[email protected]>2018-08-15 19:25:29 +0100
commita7d31b55a4292f55851bc75265643b2ae2e675df (patch)
treea3888bf27291e4336510347b86934fa243effb68 /crates
parent9f6cf42c5fd0bd98dd3445239f2c6414e8fd9324 (diff)
Simplify walk
Diffstat (limited to 'crates')
-rw-r--r--crates/libsyntax2/src/algo/walk.rs33
1 files changed, 13 insertions, 20 deletions
diff --git a/crates/libsyntax2/src/algo/walk.rs b/crates/libsyntax2/src/algo/walk.rs
index a50ec2a09..d8797c453 100644
--- a/crates/libsyntax2/src/algo/walk.rs
+++ b/crates/libsyntax2/src/algo/walk.rs
@@ -1,4 +1,7 @@
1use SyntaxNodeRef; 1use {
2 SyntaxNodeRef,
3 algo::generate,
4};
2 5
3pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> { 6pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
4 walk(root).filter_map(|event| match event { 7 walk(root).filter_map(|event| match event {
@@ -14,32 +17,22 @@ pub enum WalkEvent<'a> {
14} 17}
15 18
16pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> { 19pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> {
17 let mut done = false; 20 generate(Some(WalkEvent::Enter(root)), |pos| {
18 ::itertools::unfold(WalkEvent::Enter(root), move |pos| { 21 let next = match *pos {
19 if done {
20 return None;
21 }
22 let res = *pos;
23 *pos = match *pos {
24 WalkEvent::Enter(node) => match node.first_child() { 22 WalkEvent::Enter(node) => match node.first_child() {
25 Some(child) => WalkEvent::Enter(child), 23 Some(child) => WalkEvent::Enter(child),
26 None => WalkEvent::Exit(node), 24 None => WalkEvent::Exit(node),
27 }, 25 },
28 WalkEvent::Exit(node) => { 26 WalkEvent::Exit(node) => {
29 if node == root { 27 match node.next_sibling() {
30 done = true; 28 Some(sibling) => WalkEvent::Enter(sibling),
31 WalkEvent::Exit(node) 29 None => match node.parent() {
32 } else { 30 Some(node) => WalkEvent::Exit(node),
33 match node.next_sibling() { 31 None => return None,
34 Some(sibling) => WalkEvent::Enter(sibling), 32 },
35 None => match node.parent() {
36 Some(node) => WalkEvent::Exit(node),
37 None => WalkEvent::Exit(node),
38 },
39 }
40 } 33 }
41 } 34 }
42 }; 35 };
43 Some(res) 36 Some(next)
44 }) 37 })
45} 38}