aboutsummaryrefslogtreecommitdiff
path: root/crates/ra_syntax/src/algo/walk.rs
diff options
context:
space:
mode:
authorAleksey Kladov <[email protected]>2018-09-16 10:54:24 +0100
committerAleksey Kladov <[email protected]>2018-09-16 11:07:39 +0100
commitb5021411a84822cb3f1e3aeffad9550dd15bdeb6 (patch)
tree9dca564f8e51b298dced01c4ce669c756dce3142 /crates/ra_syntax/src/algo/walk.rs
parentba0bfeee12e19da40b5eabc8d0408639af10e96f (diff)
rename all things
Diffstat (limited to 'crates/ra_syntax/src/algo/walk.rs')
-rw-r--r--crates/ra_syntax/src/algo/walk.rs38
1 files changed, 38 insertions, 0 deletions
diff --git a/crates/ra_syntax/src/algo/walk.rs b/crates/ra_syntax/src/algo/walk.rs
new file mode 100644
index 000000000..536ee705f
--- /dev/null
+++ b/crates/ra_syntax/src/algo/walk.rs
@@ -0,0 +1,38 @@
1use {
2 SyntaxNodeRef,
3 algo::generate,
4};
5
6pub fn preorder<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = SyntaxNodeRef<'a>> {
7 walk(root).filter_map(|event| match event {
8 WalkEvent::Enter(node) => Some(node),
9 WalkEvent::Exit(_) => None,
10 })
11}
12
13#[derive(Debug, Copy, Clone)]
14pub enum WalkEvent<'a> {
15 Enter(SyntaxNodeRef<'a>),
16 Exit(SyntaxNodeRef<'a>),
17}
18
19pub fn walk<'a>(root: SyntaxNodeRef<'a>) -> impl Iterator<Item = WalkEvent<'a>> {
20 generate(Some(WalkEvent::Enter(root)), move |pos| {
21 let next = match *pos {
22 WalkEvent::Enter(node) => match node.first_child() {
23 Some(child) => WalkEvent::Enter(child),
24 None => WalkEvent::Exit(node),
25 },
26 WalkEvent::Exit(node) => {
27 if node == root {
28 return None;
29 }
30 match node.next_sibling() {
31 Some(sibling) => WalkEvent::Enter(sibling),
32 None => WalkEvent::Exit(node.parent().unwrap()),
33 }
34 }
35 };
36 Some(next)
37 })
38}