1use gramatika::Token as _;
4
5use crate::{
6 common::{AttributeList, TypeDecl},
7 decl::{
8 legacy::{ExtensionDecl, ModuleDecl},
9 Decl, FieldDecl, FunctionDecl, ImportDecl, ImportPath, ImportPathBlock, ImportPathDecl,
10 NamespacedImportPath, ParamDecl, StructDecl, TypeAliasDecl, VarDecl,
11 },
12 expr::{
13 BinaryExpr, BitcastExpr, Expr, FnCallExpr, GroupExpr, IdentExpr, PostfixExpr, PrimaryExpr,
14 TypeCtorExpr, UnaryPostExpr, UnaryPreExpr,
15 },
16 stmt::{
17 BlockStmt, CaseStmt, ContinuingStmt, ElseStmt, ExprStmt, ForStmt, IfStmt, LoopStmt,
18 ReturnStmt, Stmt, SwitchStmt,
19 },
20 SyntaxTree, Token,
21};
22
23#[derive(Clone, Copy, Default, PartialEq, PartialOrd, Eq, Ord)]
24pub enum FlowControl {
25 #[default]
26 Continue,
27 Break,
28}
29
30#[allow(unused_variables)]
31#[rustfmt::skip]
32pub trait Visitor {
33 #[must_use] fn visit_decl(&mut self, decl: &Decl) -> FlowControl { FlowControl::Continue }
34 #[must_use] fn visit_stmt(&mut self, stmt: &Stmt) -> FlowControl { FlowControl::Continue }
35 #[must_use] fn visit_expr(&mut self, expr: &Expr) -> FlowControl { FlowControl::Continue }
36
37 #[must_use] fn visit_type(&mut self, decl: &TypeDecl) -> FlowControl { FlowControl::Continue }
38 fn visit_attributes(&mut self, attr: &AttributeList) {}
39
40 #[must_use] fn visit_var_decl(&mut self, decl: &VarDecl) -> FlowControl { FlowControl::Continue }
41 #[must_use] fn visit_type_alias_decl(&mut self, decl: &TypeAliasDecl) -> FlowControl { FlowControl::Continue }
42 #[must_use] fn visit_struct_decl(&mut self, decl: &StructDecl) -> FlowControl { FlowControl::Continue }
43 #[must_use] fn visit_field_decl(&mut self, decl: &FieldDecl) -> FlowControl { FlowControl::Continue }
44 #[must_use] fn visit_func_decl(&mut self, decl: &FunctionDecl) -> FlowControl { FlowControl::Continue }
45 #[must_use] fn visit_param_decl(&mut self, decl: &ParamDecl) -> FlowControl { FlowControl::Continue }
46 #[must_use] fn visit_import_path_decl(&mut self, decl: &ImportPathDecl) -> FlowControl { FlowControl::Continue }
47 #[must_use] fn visit_import_decl(&mut self, decl: &ImportDecl) -> FlowControl { FlowControl::Continue }
48 #[must_use] fn visit_import_path(&mut self, path: &ImportPath) -> FlowControl { FlowControl::Continue }
49 fn visit_extension_decl(&mut self, decl: &ExtensionDecl) {}
50 fn visit_module_decl(&mut self, decl: &ModuleDecl) {}
51
52 #[must_use] fn visit_return_stmt(&mut self, stmt: &ReturnStmt) -> FlowControl { FlowControl::Continue }
53 #[must_use] fn visit_if_stmt(&mut self, stmt: &IfStmt) -> FlowControl { FlowControl::Continue }
54 #[must_use] fn visit_else_stmt(&mut self, stmt: &ElseStmt) -> FlowControl { FlowControl::Continue }
55 #[must_use] fn visit_switch_stmt(&mut self, stmt: &SwitchStmt) -> FlowControl { FlowControl::Continue }
56 #[must_use] fn visit_case_stmt(&mut self, stmt: &CaseStmt) -> FlowControl { FlowControl::Continue }
57 #[must_use] fn visit_loop_stmt(&mut self, stmt: &LoopStmt) -> FlowControl { FlowControl::Continue }
58 #[must_use] fn visit_continuing_stmt(&mut self, stmt: &ContinuingStmt) -> FlowControl { FlowControl::Continue }
59 #[must_use] fn visit_for_stmt(&mut self, stmt: &ForStmt) -> FlowControl { FlowControl::Continue }
60 #[must_use] fn visit_expr_stmt(&mut self, stmt: &ExprStmt) -> FlowControl { FlowControl::Continue }
61
62 #[must_use] fn visit_unary_pre_expr(&mut self, expr: &UnaryPreExpr) -> FlowControl { FlowControl::Continue }
63 #[must_use] fn visit_unary_post_expr(&mut self, expr: &UnaryPostExpr) -> FlowControl { FlowControl::Continue }
64 #[must_use] fn visit_binary_expr(&mut self, expr: &BinaryExpr) -> FlowControl { FlowControl::Continue }
65 #[must_use] fn visit_assignment_expr(&mut self, expr: &BinaryExpr) -> FlowControl { FlowControl::Continue }
66 #[must_use] fn visit_fn_call_expr(&mut self, expr: &FnCallExpr) -> FlowControl { FlowControl::Continue }
67 #[must_use] fn visit_type_ctor_expr(&mut self, expr: &TypeCtorExpr) -> FlowControl { FlowControl::Continue }
68 #[must_use] fn visit_group_expr(&mut self, expr: &GroupExpr) -> FlowControl { FlowControl::Continue }
69 #[must_use] fn visit_bitcast_expr(&mut self, expr: &BitcastExpr) -> FlowControl { FlowControl::Continue }
70 #[must_use] fn visit_primary_expr(&mut self, expr: &PrimaryExpr) -> FlowControl { FlowControl::Continue }
71 #[must_use] fn visit_postfix_expr(&mut self, expr: &PostfixExpr) -> FlowControl { FlowControl::Continue }
72 fn visit_literal_expr(&mut self, expr: &Token) {}
73 fn visit_ident_expr(&mut self, expr: &IdentExpr) {}
74}
75
76pub trait Walk {
77 fn walk(&self, visitor: &mut dyn Visitor);
78}
79
80impl Walk for SyntaxTree {
81 fn walk(&self, visitor: &mut dyn Visitor) {
82 for decl in self.inner.iter() {
83 decl.walk(visitor);
84 }
85 }
86}
87
88impl Walk for Decl {
91 fn walk(&self, visitor: &mut dyn Visitor) {
92 use Decl::*;
93
94 if visitor.visit_decl(self) == FlowControl::Continue {
95 match self {
96 Var(decl) | Const(decl) => decl.walk(visitor),
97 TypeAlias(decl) => decl.walk(visitor),
98 Struct(decl) => decl.walk(visitor),
99 Field(decl) => decl.walk(visitor),
100 Function(decl) => decl.walk(visitor),
101 Param(decl) => decl.walk(visitor),
102 Extension(decl) => decl.walk(visitor),
103 ImportPath(decl) => decl.walk(visitor),
104 Import(decl) => decl.walk(visitor),
105 Module(decl) => decl.walk(visitor),
106 }
107 }
108 }
109}
110
111impl Walk for VarDecl {
112 fn walk(&self, visitor: &mut dyn Visitor) {
113 if visitor.visit_var_decl(self) == FlowControl::Continue {
114 if let Some(ref attributes) = self.attributes {
115 visitor.visit_attributes(attributes);
116 }
117
118 if let Some(ref ty) = self.ty {
119 ty.walk(visitor);
120 }
121
122 if let Some(ref expr) = self.assignment {
123 expr.walk(visitor);
124 }
125 }
126 }
127}
128
129impl Walk for TypeAliasDecl {
130 fn walk(&self, visitor: &mut dyn Visitor) {
131 if visitor.visit_type_alias_decl(self) == FlowControl::Continue {
132 self.value.walk(visitor);
133 }
134 }
135}
136
137impl Walk for StructDecl {
138 fn walk(&self, visitor: &mut dyn Visitor) {
139 if visitor.visit_struct_decl(self) == FlowControl::Continue {
140 for field in self.body.fields.iter() {
141 field.walk(visitor);
142 }
143 }
144 }
145}
146
147impl Walk for FieldDecl {
148 fn walk(&self, visitor: &mut dyn Visitor) {
149 if visitor.visit_field_decl(self) == FlowControl::Continue {
150 self.ty.walk(visitor);
151 }
152 }
153}
154
155impl Walk for FunctionDecl {
156 fn walk(&self, visitor: &mut dyn Visitor) {
157 if visitor.visit_func_decl(self) == FlowControl::Continue {
158 for param in self.params.iter() {
159 param.walk(visitor);
160 }
161
162 if let Some(ref ty) = self.return_ty {
163 ty.walk(visitor);
164 }
165
166 self.body.walk(visitor);
167 }
168 }
169}
170
171impl Walk for ParamDecl {
172 fn walk(&self, visitor: &mut dyn Visitor) {
173 if visitor.visit_param_decl(self) == FlowControl::Continue {
174 self.ty.walk(visitor);
175 }
176 }
177}
178
179impl Walk for ExtensionDecl {
180 fn walk(&self, visitor: &mut dyn Visitor) {
181 visitor.visit_extension_decl(self);
182 }
183}
184
185impl Walk for ImportPathDecl {
186 fn walk(&self, visitor: &mut dyn Visitor) {
187 if visitor.visit_import_path_decl(self) == FlowControl::Continue {
188 self.path.walk(visitor);
189 }
190 }
191}
192
193impl Walk for ImportDecl {
194 fn walk(&self, visitor: &mut dyn Visitor) {
195 if visitor.visit_import_decl(self) == FlowControl::Continue {
196 self.path.walk(visitor);
197 }
198 }
199}
200
201impl Walk for ImportPath {
202 fn walk(&self, visitor: &mut dyn Visitor) {
203 if visitor.visit_import_path(self) == FlowControl::Continue {
204 match self {
205 ImportPath::Namespaced(NamespacedImportPath { path, .. }) => {
206 path.walk(visitor);
207 }
208 ImportPath::Block(ImportPathBlock { paths, .. }) => {
209 for path in paths.iter() {
210 path.walk(visitor);
211 }
212 }
213 ImportPath::Leaf(_) => {}
214 }
215 }
216 }
217}
218
219impl Walk for ModuleDecl {
220 fn walk(&self, visitor: &mut dyn Visitor) {
221 visitor.visit_module_decl(self);
222 }
223}
224
225impl Walk for Stmt {
228 fn walk(&self, visitor: &mut dyn Visitor) {
229 use Stmt::*;
230
231 if visitor.visit_stmt(self) == FlowControl::Continue {
232 match self {
233 Block(stmt) => stmt.walk(visitor),
234 Return(stmt) => stmt.walk(visitor),
235 If(stmt) => stmt.walk(visitor),
236 Switch(stmt) => stmt.walk(visitor),
237 Loop(stmt) => stmt.walk(visitor),
238 Continuing(stmt) => stmt.walk(visitor),
239 For(stmt) => stmt.walk(visitor),
240 Var(decl) => decl.walk(visitor),
241 Expr(stmt) => stmt.walk(visitor),
242 _ => {}
243 }
244 }
245 }
246}
247
248impl Walk for BlockStmt {
249 fn walk(&self, visitor: &mut dyn Visitor) {
250 for stmt in self.stmts.iter() {
251 stmt.walk(visitor);
252 }
253 }
254}
255
256impl Walk for ReturnStmt {
257 fn walk(&self, visitor: &mut dyn Visitor) {
258 if visitor.visit_return_stmt(self) == FlowControl::Continue {
259 if let Some(ref expr) = self.value {
260 expr.walk(visitor);
261 }
262 }
263 }
264}
265
266impl Walk for IfStmt {
267 fn walk(&self, visitor: &mut dyn Visitor) {
268 if visitor.visit_if_stmt(self) == FlowControl::Continue {
269 self.condition.walk(visitor);
270 self.then_branch.walk(visitor);
271
272 if let Some(ref stmt) = self.else_branch {
273 stmt.walk(visitor);
274 }
275 }
276 }
277}
278
279impl Walk for ElseStmt {
280 fn walk(&self, visitor: &mut dyn Visitor) {
281 if visitor.visit_else_stmt(self) == FlowControl::Continue {
282 self.body.walk(visitor);
283 }
284 }
285}
286
287impl Walk for SwitchStmt {
288 fn walk(&self, visitor: &mut dyn Visitor) {
289 if visitor.visit_switch_stmt(self) == FlowControl::Continue {
290 self.subject.walk(visitor);
291
292 for stmt in self.body.cases.iter() {
293 stmt.walk(visitor);
294 }
295 }
296 }
297}
298
299impl Walk for CaseStmt {
300 fn walk(&self, visitor: &mut dyn Visitor) {
301 if visitor.visit_case_stmt(self) == FlowControl::Continue {
302 for expr in self.selectors.iter() {
303 expr.walk(visitor);
304 }
305 self.body.walk(visitor);
306 }
307 }
308}
309
310impl Walk for LoopStmt {
311 fn walk(&self, visitor: &mut dyn Visitor) {
312 if visitor.visit_loop_stmt(self) == FlowControl::Continue {
313 self.body.walk(visitor);
314 }
315 }
316}
317
318impl Walk for ContinuingStmt {
319 fn walk(&self, visitor: &mut dyn Visitor) {
320 if visitor.visit_continuing_stmt(self) == FlowControl::Continue {
321 self.body.walk(visitor);
322 }
323 }
324}
325
326impl Walk for ForStmt {
327 fn walk(&self, visitor: &mut dyn Visitor) {
328 if visitor.visit_for_stmt(self) == FlowControl::Continue {
329 if let Some(ref stmt) = self.initializer {
330 stmt.walk(visitor);
331 }
332
333 if let Some(ref expr) = self.condition {
334 expr.walk(visitor);
335 }
336
337 if let Some(ref expr) = self.increment {
338 expr.walk(visitor);
339 }
340
341 self.body.walk(visitor);
342 }
343 }
344}
345
346impl Walk for ExprStmt {
347 fn walk(&self, visitor: &mut dyn Visitor) {
348 if visitor.visit_expr_stmt(self) == FlowControl::Continue {
349 self.expr.walk(visitor);
350 }
351 }
352}
353
354impl Walk for Expr {
357 fn walk(&self, visitor: &mut dyn Visitor) {
358 use Expr::*;
359
360 if visitor.visit_expr(self) == FlowControl::Continue {
361 match self {
362 UnaryPre(expr) => expr.walk(visitor),
363 UnaryPost(expr) => expr.walk(visitor),
364 Binary(expr) => expr.walk(visitor),
365 Assignment(expr) => expr.walk(visitor),
366 FnCall(expr) => expr.walk(visitor),
367 TypeCtor(expr) => expr.walk(visitor),
368 Group(expr) => expr.walk(visitor),
369 Bitcast(expr) => expr.walk(visitor),
370 Literal(expr) => visitor.visit_literal_expr(expr),
371 Ident(expr) => visitor.visit_ident_expr(expr),
372 Primary(expr) => expr.walk(visitor),
373 };
374 }
375 }
376}
377
378impl Walk for UnaryPreExpr {
379 fn walk(&self, visitor: &mut dyn Visitor) {
380 if visitor.visit_unary_pre_expr(self) == FlowControl::Continue {
381 self.expr.walk(visitor);
382 }
383 }
384}
385
386impl Walk for UnaryPostExpr {
387 fn walk(&self, visitor: &mut dyn Visitor) {
388 if visitor.visit_unary_post_expr(self) == FlowControl::Continue {
389 self.expr.walk(visitor);
390 }
391 }
392}
393
394impl Walk for BinaryExpr {
395 fn walk(&self, visitor: &mut dyn Visitor) {
396 let visit_method = match self.op.lexeme().as_str() {
397 "=" => Visitor::visit_assignment_expr,
398 _ => Visitor::visit_binary_expr,
399 };
400
401 if visit_method(visitor, self) == FlowControl::Continue {
402 self.lhs.walk(visitor);
403 self.rhs.walk(visitor);
404 }
405 }
406}
407
408impl Walk for FnCallExpr {
409 fn walk(&self, visitor: &mut dyn Visitor) {
410 if visitor.visit_fn_call_expr(self) == FlowControl::Continue {
411 visitor.visit_ident_expr(&self.ident);
412
413 for arg in self.arguments.arguments.iter() {
414 arg.walk(visitor);
415 }
416 }
417 }
418}
419
420impl Walk for TypeCtorExpr {
421 fn walk(&self, visitor: &mut dyn Visitor) {
422 if visitor.visit_type_ctor_expr(self) == FlowControl::Continue {
423 self.ty.walk(visitor);
424
425 for arg in self.arguments.arguments.iter() {
426 arg.walk(visitor);
427 }
428 }
429 }
430}
431
432impl Walk for GroupExpr {
433 fn walk(&self, visitor: &mut dyn Visitor) {
434 if visitor.visit_group_expr(self) == FlowControl::Continue {
435 self.expr.walk(visitor);
436 }
437 }
438}
439
440impl Walk for BitcastExpr {
441 fn walk(&self, visitor: &mut dyn Visitor) {
442 if visitor.visit_bitcast_expr(self) == FlowControl::Continue {
443 self.ty.walk(visitor);
444 self.expr.walk(visitor);
445 }
446 }
447}
448
449impl Walk for PrimaryExpr {
450 fn walk(&self, visitor: &mut dyn Visitor) {
451 if visitor.visit_primary_expr(self) == FlowControl::Continue {
452 self.expr.walk(visitor);
453
454 if let Some(ref expr) = self.postfix {
455 expr.walk(visitor);
456 }
457 }
458 }
459}
460
461impl Walk for PostfixExpr {
462 fn walk(&self, visitor: &mut dyn Visitor) {
463 if visitor.visit_postfix_expr(self) == FlowControl::Continue {
464 self.expr.walk(visitor);
465
466 if let Some(ref expr) = self.postfix {
467 expr.walk(visitor);
468 }
469 }
470 }
471}
472
473impl Walk for TypeDecl {
476 fn walk(&self, visitor: &mut dyn Visitor) {
477 if visitor.visit_type(self) == FlowControl::Continue {
478 if let Some(ref attributes) = self.attributes {
479 visitor.visit_attributes(attributes);
480 }
481
482 if let Some(ref ty) = self.child_ty {
483 ty.walk(visitor);
484 }
485
486 visitor.visit_ident_expr(&self.name);
487 }
488 }
489}