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}