Skip to main content

nargo_ir/
visitor.rs

1#![warn(missing_docs)]
2
3//! 访问者模块
4//! 
5//! 提供默认访问者实现,用于遍历和处理 IR 结构。
6
7use crate::expr::{JsExpr, JsExprVisitor, TseAttribute};
8use crate::stmt::{JsStmt, JsStmtVisitor};
9use crate::template::{ElementIR, ExpressionIR, IfNodeIR, ForNodeIR, TemplateNodeIR, TemplateNodeVisitor};
10use crate::types::Trivia;
11use nargo_types::{NargoValue, Span};
12
13/// 简单的默认访问者实现
14pub struct DefaultVisitor;
15
16impl JsExprVisitor<()> for DefaultVisitor {
17    fn visit_identifier(&mut self, _id: &String, _span: &Span, _trivia: &Trivia) -> () {}
18    fn visit_literal(&mut self, _value: &NargoValue, _span: &Span, _trivia: &Trivia) -> () {}
19    fn visit_unary(&mut self, _op: &String, argument: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
20        argument.accept(self);
21    }
22    fn visit_binary(&mut self, left: &JsExpr, _op: &String, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
23        left.accept(self);
24        right.accept(self);
25    }
26    fn visit_call(&mut self, callee: &JsExpr, args: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
27        callee.accept(self);
28        for arg in args {
29            arg.accept(self);
30        }
31    }
32    fn visit_member(&mut self, object: &JsExpr, property: &JsExpr, _computed: bool, _span: &Span, _trivia: &Trivia) -> () {
33        object.accept(self);
34        property.accept(self);
35    }
36    fn visit_optional_member(&mut self, object: &JsExpr, property: &JsExpr, _computed: bool, _span: &Span, _trivia: &Trivia) -> () {
37        object.accept(self);
38        property.accept(self);
39    }
40    fn visit_optional_call(&mut self, callee: &JsExpr, args: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
41        callee.accept(self);
42        for arg in args {
43            arg.accept(self);
44        }
45    }
46    fn visit_nullish_coalescing(&mut self, left: &JsExpr, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
47        left.accept(self);
48        right.accept(self);
49    }
50    fn visit_logical_assignment(&mut self, _op: &String, left: &JsExpr, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
51        left.accept(self);
52        right.accept(self);
53    }
54    fn visit_array(&mut self, items: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
55        for item in items {
56            item.accept(self);
57        }
58    }
59    fn visit_object(&mut self, props: &std::collections::HashMap<String, JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
60        for (_key, value) in props {
61            value.accept(self);
62        }
63    }
64    fn visit_arrow_function(&mut self, _params: &Vec<String>, body: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
65        body.accept(self);
66    }
67    fn visit_tse_element(&mut self, _tag: &String, _attributes: &Vec<TseAttribute>, children: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
68        for child in children {
69            child.accept(self);
70        }
71    }
72    fn visit_conditional(&mut self, test: &JsExpr, consequent: &JsExpr, alternate: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
73        test.accept(self);
74        consequent.accept(self);
75        alternate.accept(self);
76    }
77    fn visit_template_literal(&mut self, _quasis: &Vec<String>, expressions: &Vec<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
78        for expr in expressions {
79            expr.accept(self);
80        }
81    }
82    fn visit_spread(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
83        expr.accept(self);
84    }
85    fn visit_type_of(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
86        expr.accept(self);
87    }
88    fn visit_instance_of(&mut self, left: &JsExpr, right: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
89        left.accept(self);
90        right.accept(self);
91    }
92    fn visit_other(&mut self, _code: &String, _span: &Span, _trivia: &Trivia) -> () {}
93}
94
95impl JsStmtVisitor<()> for DefaultVisitor {
96    fn visit_expr(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
97        expr.accept(self);
98    }
99    fn visit_variable_decl(&mut self, _kind: &String, _id: &String, init: &Option<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
100        if let Some(expr) = init {
101            expr.accept(self);
102        }
103    }
104    fn visit_import(&mut self, _source: &String, _specifiers: &Vec<String>, _span: &Span, _trivia: &Trivia) -> () {}
105    fn visit_export(&mut self, declaration: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
106        declaration.accept(self);
107    }
108    fn visit_export_all(&mut self, _source: &String, _span: &Span, _trivia: &Trivia) -> () {}
109    fn visit_export_named(&mut self, _source: &Option<String>, _specifiers: &Vec<String>, _span: &Span, _trivia: &Trivia) -> () {}
110    fn visit_function_decl(&mut self, _id: &String, _params: &Vec<String>, body: &Vec<JsStmt>, _is_async: bool, _span: &Span, _trivia: &Trivia) -> () {
111        for stmt in body {
112            stmt.accept(self);
113        }
114    }
115    fn visit_return(&mut self, expr: &Option<JsExpr>, _span: &Span, _trivia: &Trivia) -> () {
116        if let Some(expr) = expr {
117            expr.accept(self);
118        }
119    }
120    fn visit_if(&mut self, test: &JsExpr, consequent: &JsStmt, alternate: &Option<Box<JsStmt>>, _span: &Span, _trivia: &Trivia) -> () {
121        test.accept(self);
122        consequent.accept(self);
123        if let Some(alt) = alternate {
124            alt.accept(self);
125        }
126    }
127    fn visit_while(&mut self, test: &JsExpr, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
128        test.accept(self);
129        body.accept(self);
130    }
131    fn visit_for(&mut self, init: &Option<Box<JsStmt>>, test: &Option<JsExpr>, update: &Option<JsExpr>, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
132        if let Some(init_stmt) = init {
133            init_stmt.accept(self);
134        }
135        if let Some(test_expr) = test {
136            test_expr.accept(self);
137        }
138        if let Some(update_expr) = update {
139            update_expr.accept(self);
140        }
141        body.accept(self);
142    }
143    fn visit_for_in(&mut self, left: &JsStmt, right: &JsExpr, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
144        left.accept(self);
145        right.accept(self);
146        body.accept(self);
147    }
148    fn visit_for_of(&mut self, left: &JsStmt, right: &JsExpr, body: &JsStmt, _span: &Span, _trivia: &Trivia) -> () {
149        left.accept(self);
150        right.accept(self);
151        body.accept(self);
152    }
153    fn visit_try(&mut self, block: &JsStmt, handler: &Option<(String, Box<JsStmt>)>, finalizer: &Option<Box<JsStmt>>, _span: &Span, _trivia: &Trivia) -> () {
154        block.accept(self);
155        if let Some((_id, body)) = handler {
156            body.accept(self);
157        }
158        if let Some(body) = finalizer {
159            body.accept(self);
160        }
161    }
162    fn visit_switch(&mut self, discriminant: &JsExpr, cases: &Vec<(Option<JsExpr>, Vec<JsStmt>)>, _span: &Span, _trivia: &Trivia) -> () {
163        discriminant.accept(self);
164        for (test, stmts) in cases {
165            if let Some(test_expr) = test {
166                test_expr.accept(self);
167            }
168            for stmt in stmts {
169                stmt.accept(self);
170            }
171        }
172    }
173    fn visit_throw(&mut self, expr: &JsExpr, _span: &Span, _trivia: &Trivia) -> () {
174        expr.accept(self);
175    }
176    fn visit_block(&mut self, stmts: &Vec<JsStmt>, _span: &Span, _trivia: &Trivia) -> () {
177        for stmt in stmts {
178            stmt.accept(self);
179        }
180    }
181    fn visit_break(&mut self, _span: &Span, _trivia: &Trivia) -> () {}
182    fn visit_continue(&mut self, _span: &Span, _trivia: &Trivia) -> () {}
183    fn visit_other(&mut self, _code: &String, _span: &Span, _trivia: &Trivia) -> () {}
184}
185
186impl TemplateNodeVisitor<()> for DefaultVisitor {
187    fn visit_element(&mut self, element: &ElementIR, depth: usize) -> () {
188        for child in &element.children {
189            child.accept(self, depth + 1);
190        }
191    }
192    fn visit_if(&mut self, if_node: &IfNodeIR, depth: usize) -> () {
193        for node in &if_node.consequent {
194            node.accept(self, depth + 1);
195        }
196        if let Some(alternate) = &if_node.alternate {
197            for node in alternate {
198                node.accept(self, depth + 1);
199            }
200        }
201        for (_condition, body) in &if_node.else_ifs {
202            for node in body {
203                node.accept(self, depth + 1);
204            }
205        }
206    }
207    fn visit_for(&mut self, for_node: &ForNodeIR, depth: usize) -> () {
208        for node in &for_node.body {
209            node.accept(self, depth + 1);
210        }
211    }
212    fn visit_text(&mut self, _text: &String, _span: &Span, _trivia: &Trivia, _depth: usize) -> () {}
213    fn visit_interpolation(&mut self, _expr: &ExpressionIR, _depth: usize) -> () {}
214    fn visit_comment(&mut self, _comment: &String, _span: &Span, _trivia: &Trivia, _depth: usize) -> () {}
215    fn visit_hoisted(&mut self, _key: &String, _depth: usize) -> () {}
216}