1use crate::{
2 error_meta::ContextualError,
3 lexer::{self, locations::GetSpan},
4};
5
6use super::{
7 ast::{
8 result::ParsedNode, Attribute, CallExpr, ConstantDeclaration, Endpoint, Expression,
9 ExpressionList, Item, Literal, ObjectEntry, Program, Request, Statement, StringLiteral,
10 TemplateStringPart, VariableDeclaration,
11 },
12 error::ParseError,
13};
14
15pub trait Visitor<'source>
16where
17 Self: std::marker::Sized,
18{
19 fn visit_program(&mut self, program: &Program<'source>) {
20 program.visit_children_with(self);
21 }
22
23 fn visit_item(&mut self, item: &Item<'source>) {
24 item.visit_children_with(self);
25 }
26
27 fn visit_variable_declaration(&mut self, declaration: &VariableDeclaration<'source>) {
28 declaration.visit_children_with(self);
29 }
30
31 fn visit_constant_declaration(&mut self, declaration: &ConstantDeclaration<'source>) {
32 declaration.visit_children_with(self);
33 }
34
35 fn visit_request(&mut self, request: &Request<'source>) {
36 request.visit_children_with(self);
37 }
38
39 fn visit_statement(&mut self, statement: &Statement<'source>) {
40 statement.visit_children_with(self);
41 }
42
43 fn visit_endpoint(&mut self, endpoint: &Endpoint<'source>) {
44 endpoint.visit_children_with(self);
45 }
46
47 fn visit_template_string_part(&mut self, part: &TemplateStringPart<'source>) {
48 part.visit_children_with(self);
49 }
50
51 fn visit_expr(&mut self, expr: &Expression<'source>) {
52 expr.visit_children_with(self);
53 }
54
55 fn visit_object_entry(&mut self, entry: &ObjectEntry<'source>) {
56 entry.visit_children_with(self);
57 }
58
59 fn visit_attribute(&mut self, attribute: &Attribute<'source>) {
60 attribute.visit_children_with(self);
61 }
62
63 fn visit_line_comment(&mut self, comment: &Literal<'source>) {
64 comment.visit_children_with(self);
65 }
66
67 fn visit_expr_list(&mut self, expr_list: &ExpressionList<'source>) {
68 expr_list.visit_children_with(self);
69 }
70
71 fn visit_literal(&mut self, stringlit: &Literal<'source>) {
72 stringlit.visit_children_with(self);
73 }
74
75 fn visit_string(&mut self, stringlit: &StringLiteral<'source>) {
76 stringlit.visit_children_with(self);
77 }
78
79 fn visit_call_expr(&mut self, expr: &CallExpr<'source>) {
80 expr.visit_children_with(self);
81 }
82
83 fn visit_token(&mut self, token: &lexer::Token<'source>) {
84 token.visit_children_with(self);
85 }
86
87 fn visit_parsed_node<T: GetSpan + VisitWith<'source>>(
88 &mut self,
89 node: &ParsedNode<'source, T>,
90 ) {
91 node.visit_children_with(self);
92 }
93
94 fn visit_error(&mut self, err: &ContextualError<ParseError<'source>>) {
95 err.visit_children_with(self);
96 }
97}
98
99pub trait VisitWith<'source> {
100 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V);
101 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V);
102}
103
104impl<'source> VisitWith<'source> for Program<'source> {
105 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
106 visitor.visit_program(self);
107 }
108
109 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
110 for item in self.items.iter() {
111 visitor.visit_item(item);
112 }
113 }
114}
115
116impl<'source> VisitWith<'source> for Item<'source> {
117 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
118 visitor.visit_item(self);
119 }
120
121 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
122 match self {
123 Item::Set(set_d) => {
124 visitor.visit_constant_declaration(set_d);
125 }
126 Item::Let(let_d) => {
127 visitor.visit_variable_declaration(let_d);
128 }
129 Item::Request(req) => {
130 visitor.visit_request(req);
131 }
132 Item::Expr(expr) => visitor.visit_expr(expr),
133 Item::Attribute(att) => visitor.visit_attribute(att),
134 Item::Error(e) => visitor.visit_error(e),
135 Item::LineComment(comment) => visitor.visit_line_comment(comment),
136 }
137 }
138}
139
140impl<'source> VisitWith<'source> for ConstantDeclaration<'source> {
141 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
142 visitor.visit_constant_declaration(self);
143 }
144
145 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
146 let ConstantDeclaration { identifier, value } = self;
147
148 visitor.visit_parsed_node(identifier);
149 visitor.visit_expr(value);
150 }
151}
152
153impl<'source> VisitWith<'source> for VariableDeclaration<'source> {
154 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
155 visitor.visit_variable_declaration(self);
156 }
157
158 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
159 let VariableDeclaration { identifier, value } = self;
160
161 visitor.visit_parsed_node(identifier);
162 visitor.visit_expr(value);
163 }
164}
165
166impl<'source> VisitWith<'source> for Request<'source> {
167 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
168 visitor.visit_request(self);
169 }
170
171 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
172 match self {
173 Request {
174 endpoint,
175 block: Some(block),
176 ..
177 } => {
178 visitor.visit_endpoint(endpoint);
179 for statement in block.statements.iter() {
180 visitor.visit_statement(statement)
181 }
182 }
183 Request { endpoint, .. } => visitor.visit_endpoint(endpoint),
184 }
185 }
186}
187
188impl<'source> VisitWith<'source> for Statement<'source> {
189 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
190 visitor.visit_statement(self)
191 }
192
193 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
194 match self {
195 Statement::Header { name, value } => {
196 visitor.visit_parsed_node(name);
197 visitor.visit_expr(value);
198 }
199 Statement::Body { value, .. } => visitor.visit_expr(value),
200 Statement::Error(e) => visitor.visit_error(e),
201 Statement::LineComment(_) => {}
202 }
203 }
204}
205
206impl<'source> VisitWith<'source> for Endpoint<'source> {
207 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
208 visitor.visit_endpoint(self)
209 }
210
211 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
212 if let Endpoint::Expr(e) = self {
213 visitor.visit_expr(e)
214 }
215 }
216}
217
218impl<'source> VisitWith<'source> for ExpressionList<'source> {
219 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
220 visitor.visit_expr_list(self)
221 }
222
223 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
224 for expr in self.expressions() {
225 visitor.visit_expr(expr);
226 }
227 }
228}
229
230impl<'source> VisitWith<'source> for TemplateStringPart<'source> {
231 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
232 visitor.visit_template_string_part(self)
233 }
234
235 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
236 match self {
237 TemplateStringPart::ExpressionPart(expr) => visitor.visit_expr(expr),
238 TemplateStringPart::StringPart(s) => visitor.visit_string(s),
239 };
240 }
241}
242
243impl<'source> VisitWith<'source> for Expression<'source> {
244 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
245 visitor.visit_expr(self)
246 }
247
248 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
249 match self {
250 Expression::Call(expr) => visitor.visit_call_expr(expr),
251 Expression::Array(list) => {
252 for expr in list.expressions() {
253 visitor.visit_expr(expr)
254 }
255 }
256 Expression::Object(entry_list) => {
257 for entry in entry_list.entries() {
258 visitor.visit_object_entry(entry)
259 }
260 }
261 Expression::TemplateStringLiteral { parts, .. } => {
262 for expr in parts.iter() {
263 visitor.visit_template_string_part(expr)
264 }
265 }
266 Expression::Error(e) => visitor.visit_error(e),
267 Expression::Identifier(ident) => visitor.visit_parsed_node(ident),
268 Expression::String(s) => visitor.visit_string(s),
269 _ => {}
270 };
271 }
272}
273
274impl<'source> VisitWith<'source> for ObjectEntry<'source> {
275 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
276 visitor.visit_object_entry(self);
277 }
278
279 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
280 visitor.visit_parsed_node(&self.key);
281 visitor.visit_expr(&self.value)
282 }
283}
284
285impl<'source> VisitWith<'source> for Attribute<'source> {
286 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
287 visitor.visit_attribute(self);
288 }
289
290 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
291 visitor.visit_parsed_node(&self.identifier);
292
293 if let Attribute {
294 arguments: Some(arguments),
295 ..
296 } = self
297 {
298 for arg in arguments.expressions() {
299 visitor.visit_expr(arg);
300 }
301 }
302 }
303}
304
305impl<'source> VisitWith<'source> for Literal<'source> {
306 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
307 visitor.visit_literal(self);
308 }
309
310 fn visit_children_with<V: Visitor<'source>>(&self, _visitor: &mut V) {}
311}
312
313impl<'source> VisitWith<'source> for StringLiteral<'source> {
314 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
315 visitor.visit_string(self)
316 }
317
318 fn visit_children_with<V: Visitor<'source>>(&self, _visitor: &mut V) {}
319}
320
321impl<'source> VisitWith<'source> for lexer::Token<'source> {
322 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
323 visitor.visit_token(self)
324 }
325
326 fn visit_children_with<V: Visitor<'source>>(&self, _visitor: &mut V) {}
327}
328
329impl<'source> VisitWith<'source> for CallExpr<'source> {
330 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
331 visitor.visit_call_expr(self)
332 }
333
334 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
335 visitor.visit_parsed_node(&self.identifier);
336 for arg in self.arguments.expressions() {
337 visitor.visit_expr(arg)
338 }
339 }
340}
341
342impl<'source> VisitWith<'source> for ContextualError<ParseError<'source>> {
343 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
344 visitor.visit_error(self)
345 }
346
347 fn visit_children_with<V: Visitor<'source>>(&self, _visitor: &mut V) {}
348}
349
350impl<'source, T: GetSpan + VisitWith<'source>> VisitWith<'source> for ParsedNode<'source, T> {
351 fn visit_with<V: Visitor<'source>>(&self, visitor: &mut V) {
352 visitor.visit_parsed_node(self)
353 }
354
355 fn visit_children_with<V: Visitor<'source>>(&self, visitor: &mut V) {
356 match self {
357 ParsedNode::Ok(node) => node.visit_with(visitor),
358 ParsedNode::Error(e) => {
359 visitor.visit_error(e);
360 }
361 }
362 }
363}