1use crate::{
6 Language,
7 tree::red_tree::{RedLeaf, RedNode, RedTree},
8};
9
10pub trait Visitor<'a, L: Language> {
12 fn visit_node(&mut self, node: RedNode<'a, L>);
14
15 fn visit_token(&mut self, token: RedLeaf<L>);
17
18 fn walk_node(&mut self, node: RedNode<'a, L>) {
20 for child in node.children() {
21 match child {
22 RedTree::Node(n) => self.visit_node(n),
23 RedTree::Leaf(t) => self.visit_token(t),
24 }
25 }
26 }
27}
28
29pub struct PreOrder<'a, L: Language> {
31 stack: Vec<RedTree<'a, L>>,
32}
33
34impl<'a, L: Language> PreOrder<'a, L> {
35 pub fn new(root: RedTree<'a, L>) -> Self {
37 Self { stack: vec![root] }
38 }
39}
40
41impl<'a, L: Language> Iterator for PreOrder<'a, L> {
42 type Item = RedTree<'a, L>;
43
44 fn next(&mut self) -> Option<Self::Item> {
45 let next = self.stack.pop()?;
46
47 if let RedTree::Node(node) = next {
48 let children = node.green.children();
50 let mut offset = node.offset + node.green.text_len() as usize;
51
52 for child in children.iter().rev() {
53 offset -= child.len() as usize;
54 match child {
55 crate::GreenTree::Node(n) => {
56 self.stack.push(RedTree::Node(RedNode::new(n, offset)));
57 }
58 crate::GreenTree::Leaf(t) => {
59 self.stack.push(RedTree::Leaf(RedLeaf { kind: t.kind, span: core::range::Range { start: offset, end: offset + t.length as usize } }));
60 }
61 }
62 }
63 }
64
65 Some(next)
66 }
67}