mago_traverser/lib.rs
1#![allow(unused_variables)]
2
3use mago_ast::Node;
4
5/// Traverse a given node using the given visitor.
6///
7/// # Parameters
8///
9/// - `node`: The node that is traversed.
10/// - `visitor`: The visitor that is used to traverse the node.
11/// - `context`: The context that is passed to the visitor.
12///
13/// # Lifetimes
14///
15/// - `'ast`: The lifetime of the AST nodes that are visited.
16pub fn traverse<TContext>(node: Node<'_>, visitor: &dyn NodeVisitor<TContext>, context: &mut TContext) {
17 visitor.enter(&node, context);
18
19 for child in node.children() {
20 traverse(child, visitor, context);
21 }
22
23 visitor.exit(&node, context);
24}
25
26/// Traverse a given node using the given mutable visitor.
27///
28/// # Parameters
29///
30/// - `node`: The node that is traversed.
31/// - `visitor`: The visitor that is used to traverse the node.
32/// - `context`: The context that is passed to the visitor.
33///
34/// # Lifetimes
35///
36/// - `'ast`: The lifetime of the AST nodes that are visited.
37pub fn traverse_mut<TContext>(node: Node<'_>, visitor: &mut dyn MutNodeVisitor<TContext>, context: &mut TContext) {
38 visitor.enter_mut(&node, context);
39
40 for child in node.children() {
41 traverse_mut(child, visitor, context);
42 }
43
44 visitor.enter_mut(&node, context);
45}
46
47/// A visitor that can be used to traverse an AST.
48///
49/// # Type Parameters
50///
51/// - `TContext`: The type of the context that is passed to the visitor.
52pub trait NodeVisitor<TContext>: Sync + Send {
53 /// Called when the visitor enters a node.
54 ///
55 /// # Parameters
56 ///
57 /// - `node`: The node that is entered.
58 ///
59 /// # Lifetimes
60 ///
61 /// - `'ast`: The lifetime of the AST nodes that are visited.
62 fn enter(&self, node: &Node<'_>, context: &mut TContext);
63
64 /// Called when the visitor exits a node.
65 ///
66 /// # Parameters
67 ///
68 /// - `node`: The node that is exited.
69 ///
70 /// # Lifetimes
71 ///
72 /// - `'ast`: The lifetime of the AST nodes that are visited.
73 fn exit(&self, node: &Node<'_>, context: &mut TContext) {
74 // Do nothing by default.
75 }
76}
77
78/// A visitor that can be used to traverse an AST and modify the nodes.
79///
80/// # Type Parameters
81///
82/// - `TContext`: The type of the context that is passed to the visitor.
83pub trait MutNodeVisitor<TContext>: Sync + Send {
84 /// Called when the visitor enters a node.
85 ///
86 /// # Parameters
87 ///
88 /// - `node`: The node that is entered.
89 ///
90 /// # Lifetimes
91 ///
92 /// - `'ast`: The lifetime of the AST nodes that are visited.
93 fn enter_mut(&mut self, node: &Node<'_>, context: &mut TContext);
94
95 /// Called when the visitor exits a node.
96 ///
97 /// # Parameters
98 ///
99 /// - `node`: The node that is exited.
100 ///
101 /// # Lifetimes
102 ///
103 /// - `'ast`: The lifetime of the AST nodes that are visited.
104 fn exit_mut(&mut self, node: &Node<'_>, context: &mut TContext) {
105 // Do nothing by default.
106 }
107}
108
109/// Implement the `MutNodeVisitor` trait for any type that implements the `NodeVisitor` trait.
110impl<T> MutNodeVisitor<T> for dyn NodeVisitor<T> {
111 fn enter_mut(&mut self, node: &Node<'_>, context: &mut T) {
112 self.enter(node, context);
113 }
114
115 fn exit_mut(&mut self, node: &Node<'_>, context: &mut T) {
116 self.exit(node, context);
117 }
118}