rested/parser/
ast_visit.rs

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}