scilla_parser/ast/
visitor.rs

1use crate::ast::{converting::AstConverting, nodes::*};
2
3use super::{TraversalResult, TreeTraversalMode};
4
5/// The `AstVisitor` trait is used for implementing the visiting behaviour for each AST node of the Scilla AST.
6/// Each node in the AST implements this trait to define how it should be visited during the tree traversal.
7/// The `visit` method is called with an `emitter` that implements the `AstConverting` trait, which is responsible for converting the AST to some other form.
8/// The `visit` method returns a `Result` with a `TraversalResult` that informs the visitor algorithm how to proceed, or a `String` in case of an error.
9pub trait AstVisitor {
10    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String>;
11}
12
13impl<T: AstVisitor> AstVisitor for WithMetaData<T> {
14    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
15        emitter.push_source_position(&self.start, &self.end);
16        let ret = self.node.visit(emitter);
17        emitter.pop_source_position();
18
19        ret
20    }
21}
22
23impl AstVisitor for NodeByteStr {
24    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
25        let ret = emitter.emit_byte_str(TreeTraversalMode::Enter, self)?;
26
27        // No children
28
29        match ret {
30            TraversalResult::Continue => emitter.emit_byte_str(TreeTraversalMode::Exit, self),
31            _ => Ok(TraversalResult::Continue),
32        }
33    }
34}
35
36impl AstVisitor for NodeTypeNameIdentifier {
37    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
38        let ret = emitter.emit_type_name_identifier(TreeTraversalMode::Enter, self);
39
40        let children_ret = if ret == Ok(TraversalResult::Continue) {
41            match self {
42                NodeTypeNameIdentifier::ByteStringType(bs_type) => bs_type.visit(emitter),
43                _ => Ok(TraversalResult::Continue),
44            }
45        } else {
46            ret
47        }?;
48
49        match children_ret {
50            TraversalResult::Continue => {
51                emitter.emit_type_name_identifier(TreeTraversalMode::Exit, self)
52            }
53            _ => Ok(TraversalResult::Continue),
54        }
55    }
56}
57
58impl AstVisitor for NodeImportedName {
59    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
60        let ret = emitter.emit_imported_name(TreeTraversalMode::Enter, self);
61
62        let children_ret = if ret == Ok(TraversalResult::Continue) {
63            match self {
64                NodeImportedName::RegularImport(name) => name.visit(emitter),
65                NodeImportedName::AliasedImport(name, alias) => {
66                    name.visit(emitter)?;
67                    alias.visit(emitter)
68                }
69            }
70        } else {
71            ret
72        }?;
73
74        match children_ret {
75            TraversalResult::Continue => emitter.emit_imported_name(TreeTraversalMode::Exit, self),
76            _ => Ok(TraversalResult::Continue),
77        }
78    }
79}
80
81impl AstVisitor for NodeImportDeclarations {
82    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
83        let ret = emitter.emit_import_declarations(TreeTraversalMode::Enter, self);
84        let children_ret = if ret == Ok(TraversalResult::Continue) {
85            for import in &self.import_list {
86                import.visit(emitter)?;
87            }
88            Ok(TraversalResult::Continue)
89        } else {
90            ret
91        }?;
92        match children_ret {
93            TraversalResult::Continue => {
94                emitter.emit_import_declarations(TreeTraversalMode::Exit, self)
95            }
96            _ => Ok(TraversalResult::Continue),
97        }
98    }
99}
100
101impl AstVisitor for NodeMetaIdentifier {
102    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
103        let ret = emitter.emit_meta_identifier(TreeTraversalMode::Enter, self);
104        let children_ret = if ret == Ok(TraversalResult::Continue) {
105            match self {
106                NodeMetaIdentifier::MetaName(name) => name.visit(emitter),
107                NodeMetaIdentifier::MetaNameInNamespace(name, ns) => {
108                    name.visit(emitter)?;
109                    ns.visit(emitter)
110                }
111                NodeMetaIdentifier::MetaNameInHexspace(_, name) => name.visit(emitter),
112                NodeMetaIdentifier::ByteString => Ok(TraversalResult::Continue),
113            }
114        } else {
115            ret
116        }?;
117        match children_ret {
118            TraversalResult::Continue => {
119                emitter.emit_meta_identifier(TreeTraversalMode::Exit, self)
120            }
121            _ => Ok(TraversalResult::Continue),
122        }
123    }
124}
125
126impl AstVisitor for NodeVariableIdentifier {
127    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
128        let ret = emitter.emit_variable_identifier(TreeTraversalMode::Enter, self);
129        let children_ret = if ret == Ok(TraversalResult::Continue) {
130            match self {
131                NodeVariableIdentifier::VariableInNamespace(type_name_identifier, _) => {
132                    type_name_identifier.visit(emitter)
133                }
134                // Since VariableName and SpecialIdentifier don't have children
135                // we can directly return ret here.
136                _ => ret,
137            }
138        } else {
139            ret
140        }?;
141        match children_ret {
142            TraversalResult::Continue => {
143                emitter.emit_variable_identifier(TreeTraversalMode::Exit, self)
144            }
145            _ => Ok(TraversalResult::Continue),
146        }
147    }
148}
149
150impl AstVisitor for NodeBuiltinArguments {
151    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
152        // Call the code emitter at the entry of the NodeBuiltinArguments
153        let ret = emitter.emit_builtin_arguments(TreeTraversalMode::Enter, self);
154        // Call the visitor on all children of NodeBuiltinArguments if ret == Ok(TraversalResult::Continue)
155        let children_ret = if ret == Ok(TraversalResult::Continue) {
156            // Visit each of the arguments
157            self.arguments
158                .iter()
159                .map(|argument| argument.visit(emitter))
160                .find(|r| *r == Err(String::from("Failure")))
161                .unwrap_or(Ok(TraversalResult::Continue))
162        } else {
163            ret
164        }?;
165        // Call the code emitter at the exit of the NodeBuiltinArguments
166        match children_ret {
167            TraversalResult::Continue => {
168                emitter.emit_builtin_arguments(TreeTraversalMode::Exit, self)
169            }
170            _ => Ok(TraversalResult::Continue),
171        }
172    }
173}
174
175impl AstVisitor for NodeTypeMapKey {
176    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
177        let ret = emitter.emit_type_map_key(TreeTraversalMode::Enter, self);
178        let children_ret = if ret == Ok(TraversalResult::Continue) {
179            match self {
180                NodeTypeMapKey::GenericMapKey(node_met_id) => node_met_id.visit(emitter),
181                NodeTypeMapKey::EnclosedGenericId(node_met_id) => node_met_id.visit(emitter),
182                NodeTypeMapKey::EnclosedAddressMapKeyType(node_address_type) => {
183                    node_address_type.visit(emitter)
184                }
185                NodeTypeMapKey::AddressMapKeyType(node_address_type) => {
186                    node_address_type.visit(emitter)
187                }
188            }
189        } else {
190            ret
191        }?;
192        match children_ret {
193            TraversalResult::Continue => emitter.emit_type_map_key(TreeTraversalMode::Exit, self),
194            _ => Ok(TraversalResult::Continue),
195        }
196    }
197}
198
199impl AstVisitor for NodeTypeMapValue {
200    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
201        let ret = emitter.emit_type_map_value(TreeTraversalMode::Enter, self);
202        let children_ret = if ret == Ok(TraversalResult::Continue) {
203            match self {
204                NodeTypeMapValue::MapValueTypeOrEnumLikeIdentifier(meta_id) => {
205                    meta_id.visit(emitter)
206                }
207                NodeTypeMapValue::MapKeyValue(entry) => entry.visit(emitter),
208                NodeTypeMapValue::MapValueParenthesizedType(value) => value.visit(emitter),
209                NodeTypeMapValue::MapValueAddressType(address_type) => address_type.visit(emitter),
210            }
211        } else {
212            ret
213        }?;
214        match children_ret {
215            TraversalResult::Continue => emitter.emit_type_map_value(TreeTraversalMode::Exit, self),
216            _ => Ok(TraversalResult::Continue),
217        }
218    }
219}
220
221impl AstVisitor for NodeTypeArgument {
222    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
223        let ret = emitter.emit_type_argument(TreeTraversalMode::Enter, self);
224        let children_ret = if ret == Ok(TraversalResult::Continue) {
225            match self {
226                NodeTypeArgument::EnclosedTypeArgument(node) => node.visit(emitter),
227                NodeTypeArgument::GenericTypeArgument(node) => node.visit(emitter),
228                NodeTypeArgument::TemplateTypeArgument(_) => Ok(TraversalResult::Continue),
229                NodeTypeArgument::AddressTypeArgument(node) => node.visit(emitter),
230                NodeTypeArgument::MapTypeArgument(key_node, value_node) => {
231                    match key_node.visit(emitter) {
232                        Ok(TraversalResult::Continue) => value_node.visit(emitter),
233                        Err(msg) => Err(msg),
234                        _ => Ok(TraversalResult::Continue),
235                    }
236                }
237            }
238        } else {
239            ret
240        }?;
241        match children_ret {
242            TraversalResult::Continue => emitter.emit_type_argument(TreeTraversalMode::Exit, self),
243            _ => Ok(TraversalResult::Continue),
244        }
245    }
246}
247
248impl AstVisitor for NodeScillaType {
249    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
250        let ret = emitter.emit_scilla_type(TreeTraversalMode::Enter, self);
251        let children_ret = if ret == Ok(TraversalResult::Continue) {
252            match self {
253                NodeScillaType::GenericTypeWithArgs(id, args) => {
254                    id.visit(emitter)?;
255                    for arg in args {
256                        arg.visit(emitter)?;
257                    }
258                    Ok(TraversalResult::Continue)
259                }
260                NodeScillaType::MapType(key, value) => {
261                    key.visit(emitter)?;
262                    value.visit(emitter)
263                }
264                NodeScillaType::FunctionType(t1, t2) => {
265                    t1.visit(emitter)?;
266                    t2.visit(emitter)
267                }
268                NodeScillaType::PolyFunctionType(_, t) => t.visit(emitter),
269                NodeScillaType::EnclosedType(t) => t.visit(emitter),
270                NodeScillaType::ScillaAddresseType(t) => t.visit(emitter),
271                NodeScillaType::TypeVarType(_) => Ok(TraversalResult::Continue),
272            }
273        } else {
274            ret
275        }?;
276        match children_ret {
277            TraversalResult::Continue => emitter.emit_scilla_type(TreeTraversalMode::Exit, self),
278            _ => Ok(TraversalResult::Continue),
279        }
280    }
281}
282
283impl AstVisitor for NodeTypeMapEntry {
284    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
285        let ret = emitter.emit_type_map_entry(TreeTraversalMode::Enter, self);
286        let children_ret = if ret == Ok(TraversalResult::Continue) {
287            self.key.visit(emitter)?;
288            self.value.visit(emitter)
289        } else {
290            ret
291        }?;
292        match children_ret {
293            TraversalResult::Continue => emitter.emit_type_map_entry(TreeTraversalMode::Exit, self),
294            _ => Ok(TraversalResult::Continue),
295        }
296    }
297}
298
299impl AstVisitor for NodeAddressTypeField {
300    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
301        let ret = emitter.emit_address_type_field(TreeTraversalMode::Enter, self);
302        let children_ret = if ret == Ok(TraversalResult::Continue) {
303            self.identifier.visit(emitter)?;
304            self.type_name.visit(emitter)
305        } else {
306            ret
307        }?;
308        match children_ret {
309            TraversalResult::Continue => {
310                emitter.emit_address_type_field(TreeTraversalMode::Exit, self)
311            }
312            _ => Ok(TraversalResult::Continue),
313        }
314    }
315}
316
317impl AstVisitor for NodeAddressType {
318    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
319        let ret = emitter.emit_address_type(TreeTraversalMode::Enter, self);
320        let children_ret = if ret == Ok(TraversalResult::Continue) {
321            self.identifier.visit(emitter)?;
322
323            for field in &self.address_fields {
324                let ret = field.visit(emitter);
325
326                ret.as_ref()?;
327            }
328            ret
329        } else {
330            Ok(TraversalResult::Continue)
331        }?;
332        match children_ret {
333            TraversalResult::Continue => emitter.emit_address_type(TreeTraversalMode::Exit, self),
334            _ => Ok(TraversalResult::Continue),
335        }
336    }
337}
338
339impl AstVisitor for NodeFullExpression {
340    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
341        let ret = emitter.emit_full_expression(TreeTraversalMode::Enter, self);
342        let children_ret = if ret == Ok(TraversalResult::Continue) {
343            match self {
344                NodeFullExpression::LocalVariableDeclaration {
345                    expression,
346                    containing_expression,
347                    ..
348                } => {
349                    expression.visit(emitter)?;
350                    containing_expression.visit(emitter)
351                }
352                NodeFullExpression::FunctionDeclaration { expression, .. } => {
353                    expression.visit(emitter)
354                }
355                NodeFullExpression::FunctionCall {
356                    function_name,
357                    argument_list,
358                    ..
359                } => {
360                    function_name.visit(emitter)?;
361                    for arg in argument_list {
362                        arg.visit(emitter)?;
363                    }
364                    Ok(TraversalResult::Continue)
365                }
366                NodeFullExpression::ExpressionAtomic(atom_expr) => atom_expr.visit(emitter),
367                NodeFullExpression::ExpressionBuiltin { xs, .. } => xs.visit(emitter),
368                NodeFullExpression::Message(message_entries) => {
369                    for entry in message_entries {
370                        entry.visit(emitter)?;
371                    }
372
373                    Ok(TraversalResult::Continue)
374                }
375                NodeFullExpression::Match {
376                    match_expression,
377                    clauses,
378                    ..
379                } => {
380                    match_expression.visit(emitter)?;
381                    for clause in clauses {
382                        clause.visit(emitter)?;
383                    }
384
385                    Ok(TraversalResult::Continue)
386                }
387                NodeFullExpression::ConstructorCall {
388                    identifier_name,
389                    argument_list,
390                    ..
391                } => {
392                    identifier_name.visit(emitter)?;
393                    for arg in argument_list {
394                        arg.visit(emitter)?;
395                    }
396                    Ok(TraversalResult::Continue)
397                }
398                NodeFullExpression::TemplateFunction { expression, .. } => {
399                    expression.visit(emitter)
400                }
401                NodeFullExpression::TApp {
402                    identifier_name,
403                    type_arguments,
404                    ..
405                } => {
406                    identifier_name.visit(emitter)?;
407                    for targ in type_arguments {
408                        targ.visit(emitter)?;
409                    }
410                    Ok(TraversalResult::Continue)
411                }
412            }
413        } else {
414            ret
415        }?;
416        match children_ret {
417            TraversalResult::Continue => {
418                emitter.emit_full_expression(TreeTraversalMode::Exit, self)
419            }
420            _ => Ok(TraversalResult::Continue),
421        }
422    }
423}
424
425impl AstVisitor for NodeMessageEntry {
426    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
427        let ret = emitter.emit_message_entry(TreeTraversalMode::Enter, self);
428        let children_ret = if ret == Ok(TraversalResult::Continue) {
429            match self {
430                NodeMessageEntry::MessageLiteral(var_identifier, value_literal) => {
431                    var_identifier.visit(emitter)?;
432                    value_literal.visit(emitter)
433                }
434                NodeMessageEntry::MessageVariable(var_identifier1, var_identifier2) => {
435                    var_identifier1.visit(emitter)?;
436                    emitter.push_source_position(&var_identifier2.start, &var_identifier2.end);
437                    var_identifier2.visit(emitter)
438                }
439            }
440        } else {
441            ret
442        }?;
443        match children_ret {
444            TraversalResult::Continue => emitter.emit_message_entry(TreeTraversalMode::Exit, self),
445            _ => Ok(TraversalResult::Continue),
446        }
447    }
448}
449
450impl AstVisitor for NodePatternMatchExpressionClause {
451    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
452        let ret = emitter.emit_pattern_match_expression_clause(TreeTraversalMode::Enter, self);
453        let pattern_ret = if ret == Ok(TraversalResult::Continue) {
454            self.pattern.visit(emitter)
455        } else {
456            ret
457        };
458        let expression_ret = if pattern_ret == Ok(TraversalResult::Continue) {
459            self.expression.visit(emitter)
460        } else {
461            pattern_ret
462        }?;
463        match expression_ret {
464            TraversalResult::Continue => {
465                emitter.emit_pattern_match_expression_clause(TreeTraversalMode::Exit, self)
466            }
467            _ => Ok(TraversalResult::Continue),
468        }
469    }
470}
471
472impl AstVisitor for NodeAtomicExpression {
473    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
474        let ret = emitter.emit_atomic_expression(TreeTraversalMode::Enter, self);
475        // Only visit children if entering was successful and did not result in skipping
476        let children_ret = if ret == Ok(TraversalResult::Continue) {
477            match self {
478                NodeAtomicExpression::AtomicSid(sid) => sid.visit(emitter),
479                NodeAtomicExpression::AtomicLit(lit) => lit.visit(emitter),
480            }
481        } else {
482            ret
483        }?;
484        match children_ret {
485            TraversalResult::Continue => {
486                emitter.emit_atomic_expression(TreeTraversalMode::Exit, self)
487            }
488            _ => Ok(TraversalResult::Continue),
489        }
490    }
491}
492
493impl AstVisitor for NodeContractTypeArguments {
494    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
495        let ret = emitter.emit_contract_type_arguments(TreeTraversalMode::Enter, self);
496        let children_ret = if ret == Ok(TraversalResult::Continue) {
497            self.type_arguments
498                .iter()
499                .map(|child| child.visit(emitter))
500                .find(|result| *result == Err("".into()))
501                .unwrap_or(Ok(TraversalResult::Continue))
502        } else {
503            ret
504        }?;
505        match children_ret {
506            TraversalResult::Continue => {
507                emitter.emit_contract_type_arguments(TreeTraversalMode::Exit, self)
508            }
509            _ => Ok(TraversalResult::Continue),
510        }
511    }
512}
513
514impl AstVisitor for NodeValueLiteral {
515    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
516        let ret = emitter.emit_value_literal(TreeTraversalMode::Enter, self);
517        let children_ret = if ret == Ok(TraversalResult::Continue) {
518            match self {
519                NodeValueLiteral::LiteralInt(type_name, _) => type_name.visit(emitter),
520                NodeValueLiteral::LiteralEmptyMap(type_map_key, type_map_value) => {
521                    type_map_key.visit(emitter)?;
522                    emitter.push_source_position(&type_map_value.start, &type_map_value.end);
523                    type_map_value.visit(emitter)
524                }
525                _ => Ok(TraversalResult::Continue),
526            }
527        } else {
528            ret
529        }?;
530        match children_ret {
531            TraversalResult::Continue => emitter.emit_value_literal(TreeTraversalMode::Exit, self),
532            _ => Ok(TraversalResult::Continue),
533        }
534    }
535}
536
537impl AstVisitor for NodeMapAccess {
538    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
539        let ret = emitter.emit_map_access(TreeTraversalMode::Enter, self);
540        let children_ret = if ret == Ok(TraversalResult::Continue) {
541            self.identifier_name.visit(emitter)
542        } else {
543            ret
544        }?;
545        match children_ret {
546            TraversalResult::Continue => emitter.emit_map_access(TreeTraversalMode::Exit, self),
547            _ => Ok(TraversalResult::Continue),
548        }
549    }
550}
551
552impl AstVisitor for NodePattern {
553    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
554        let ret = emitter.emit_pattern(TreeTraversalMode::Enter, self);
555        let children_ret = if ret == Ok(TraversalResult::Continue) {
556            match self {
557                NodePattern::Wildcard => Ok(TraversalResult::Continue),
558                NodePattern::Binder(_) => Ok(TraversalResult::Continue),
559                NodePattern::Constructor(identifier, argument_patterns) => {
560                    identifier.visit(emitter)?;
561                    for pattern in argument_patterns {
562                        pattern.visit(emitter)?;
563                    }
564                    Ok(TraversalResult::Continue)
565                }
566            }
567        } else {
568            ret
569        }?;
570        match children_ret {
571            TraversalResult::Continue => emitter.emit_pattern(TreeTraversalMode::Exit, self),
572            _ => Ok(TraversalResult::Continue),
573        }
574    }
575}
576
577impl AstVisitor for NodeArgumentPattern {
578    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
579        let ret = emitter.emit_argument_pattern(TreeTraversalMode::Enter, self);
580        let children_ret = if ret == Ok(TraversalResult::Continue) {
581            match self {
582                NodeArgumentPattern::WildcardArgument => Ok(TraversalResult::Continue),
583                NodeArgumentPattern::BinderArgument(_) => Ok(TraversalResult::Continue),
584                NodeArgumentPattern::ConstructorArgument(meta_identifier) => {
585                    meta_identifier.visit(emitter)
586                }
587                NodeArgumentPattern::PatternArgument(pattern) => pattern.visit(emitter),
588            }
589        } else {
590            ret
591        }?;
592        match children_ret {
593            TraversalResult::Continue => {
594                emitter.emit_argument_pattern(TreeTraversalMode::Exit, self)
595            }
596            _ => Ok(TraversalResult::Continue),
597        }
598    }
599}
600
601impl AstVisitor for NodePatternMatchClause {
602    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
603        let ret = emitter.emit_pattern_match_clause(TreeTraversalMode::Enter, self);
604        let children_ret = if ret == Ok(TraversalResult::Continue) {
605            emitter
606                .push_source_position(&self.pattern_expression.start, &self.pattern_expression.end);
607            match self.pattern_expression.visit(emitter) {
608                Err(msg) => Err(msg),
609                _ => match &self.statement_block {
610                    Some(stmt_block) => stmt_block.visit(emitter),
611                    None => Ok(TraversalResult::Continue),
612                },
613            }
614        } else {
615            ret
616        }?;
617        match children_ret {
618            TraversalResult::Continue => {
619                emitter.emit_pattern_match_clause(TreeTraversalMode::Exit, self)
620            }
621            _ => Ok(TraversalResult::Continue),
622        }
623    }
624}
625
626impl AstVisitor for NodeBlockchainFetchArguments {
627    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
628        let ret = emitter.emit_blockchain_fetch_arguments(TreeTraversalMode::Enter, self);
629        if let Ok(TraversalResult::Continue) = ret {
630            // Visit each argument
631            for arg in &self.arguments {
632                arg.visit(emitter)?;
633            }
634        }
635        match ret? {
636            TraversalResult::Continue => {
637                emitter.emit_blockchain_fetch_arguments(TreeTraversalMode::Exit, self)
638            }
639            _ => Ok(TraversalResult::Continue),
640        }
641    }
642}
643
644impl AstVisitor for NodeStatement {
645    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
646        let ret = emitter.emit_statement(TreeTraversalMode::Enter, self);
647        let children_ret = if ret == Ok(TraversalResult::Continue) {
648            match self {
649                NodeStatement::Load {
650                    right_hand_side, ..
651                }
652                | NodeStatement::Store {
653                    right_hand_side, ..
654                } => right_hand_side.visit(emitter),
655                NodeStatement::RemoteFetch(statement) => statement.visit(emitter),
656                NodeStatement::Bind {
657                    right_hand_side, ..
658                } => right_hand_side.visit(emitter),
659                NodeStatement::ReadFromBC { arguments, .. } => {
660                    if let Some(arg) = arguments {
661                        arg.visit(emitter)
662                    } else {
663                        Ok(TraversalResult::Continue)
664                    }
665                }
666                NodeStatement::MapGet { keys, .. }
667                | NodeStatement::MapUpdate { keys, .. }
668                | NodeStatement::MapGetExists { keys, .. }
669                | NodeStatement::MapUpdateDelete { keys, .. } => {
670                    for key in keys {
671                        let ret = key.visit(emitter);
672
673                        if ret != Ok(TraversalResult::Continue) {
674                            return ret;
675                        }
676                    }
677
678                    Ok(TraversalResult::Continue)
679                }
680                NodeStatement::Send {
681                    identifier_name, ..
682                }
683                | NodeStatement::CreateEvnt {
684                    identifier_name, ..
685                } => identifier_name.visit(emitter),
686                NodeStatement::Throw { error_variable, .. } => {
687                    if let Some(variable) = error_variable {
688                        variable.visit(emitter)
689                    } else {
690                        Ok(TraversalResult::Continue)
691                    }
692                }
693                NodeStatement::MatchStmt {
694                    variable, clauses, ..
695                } => {
696                    let ret = variable.visit(emitter);
697
698                    if ret != Ok(TraversalResult::Continue) {
699                        return ret;
700                    }
701                    for clause in clauses {
702                        let ret = clause.visit(emitter);
703
704                        if ret != Ok(TraversalResult::Continue) {
705                            return ret;
706                        }
707                    }
708                    Ok(TraversalResult::Continue)
709                }
710                NodeStatement::CallProc {
711                    component_id,
712                    arguments,
713                    ..
714                } => {
715                    let ret = component_id.visit(emitter);
716                    if ret != Ok(TraversalResult::Continue) {
717                        return ret;
718                    }
719                    for argument in arguments {
720                        let ret = argument.visit(emitter);
721                        if ret != Ok(TraversalResult::Continue) {
722                            return ret;
723                        }
724                    }
725                    Ok(TraversalResult::Continue)
726                }
727                NodeStatement::Iterate {
728                    identifier_name,
729                    component_id,
730                } => {
731                    let ret = identifier_name.visit(emitter);
732                    if ret != Ok(TraversalResult::Continue) {
733                        return ret;
734                    }
735
736                    component_id.visit(emitter)
737                }
738                _ => Ok(TraversalResult::Continue),
739            }
740        } else {
741            ret
742        };
743
744        match children_ret? {
745            TraversalResult::Continue => emitter.emit_statement(TreeTraversalMode::Exit, self),
746            _ => Ok(TraversalResult::Continue),
747        }
748    }
749}
750
751impl AstVisitor for NodeRemoteFetchStatement {
752    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
753        let ret = emitter.emit_remote_fetch_statement(TreeTraversalMode::Enter, self);
754        let children_ret = if ret == Ok(TraversalResult::Continue) {
755            match self {
756                NodeRemoteFetchStatement::ReadStateMutable(_, _, variable) => {
757                    variable.visit(emitter)
758                }
759                NodeRemoteFetchStatement::ReadStateMutableSpecialId(_, _, _) => {
760                    Ok(TraversalResult::Continue)
761                }
762                NodeRemoteFetchStatement::ReadStateMutableMapAccess(_, _, _, accesses) => {
763                    for access in accesses {
764                        access.visit(emitter)?;
765                    }
766                    Ok(TraversalResult::Continue)
767                }
768                NodeRemoteFetchStatement::ReadStateMutableMapAccessExists(_, _, _, accesses) => {
769                    for access in accesses {
770                        access.visit(emitter)?;
771                    }
772                    Ok(TraversalResult::Continue)
773                }
774                NodeRemoteFetchStatement::ReadStateMutableCastAddress(_, variable, address) => {
775                    variable.visit(emitter)?;
776                    address.visit(emitter)
777                }
778            }
779        } else {
780            ret
781        };
782        match children_ret? {
783            TraversalResult::Continue => {
784                emitter.emit_remote_fetch_statement(TreeTraversalMode::Exit, self)
785            }
786            _ => Ok(TraversalResult::Continue),
787        }
788    }
789}
790
791impl AstVisitor for NodeComponentId {
792    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
793        // Emit enter event
794        let ret = emitter.emit_component_id(TreeTraversalMode::Enter, self);
795        let children_ret = if ret == Ok(TraversalResult::Continue) {
796            // Handle child nodes
797            match self {
798                NodeComponentId::WithTypeLikeName(type_name_identifier) => {
799                    type_name_identifier.visit(emitter)
800                }
801                NodeComponentId::WithRegularId(_) => Ok(TraversalResult::Continue),
802            }
803        } else {
804            ret
805        };
806        match children_ret? {
807            TraversalResult::Continue => emitter.emit_component_id(TreeTraversalMode::Exit, self),
808            _ => Ok(TraversalResult::Continue),
809        }
810    }
811}
812
813impl AstVisitor for NodeComponentParameters {
814    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
815        let ret = emitter.emit_component_parameters(TreeTraversalMode::Enter, self);
816        let children_ret = if ret == Ok(TraversalResult::Continue) {
817            for param in &self.parameters {
818                param.visit(emitter)?;
819            }
820            Ok(TraversalResult::Continue)
821        } else {
822            ret
823        };
824        match children_ret? {
825            TraversalResult::Continue => {
826                emitter.emit_component_parameters(TreeTraversalMode::Exit, self)
827            }
828            _ => Ok(TraversalResult::Continue),
829        }
830    }
831}
832
833impl AstVisitor for NodeParameterPair {
834    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
835        let ret = emitter.emit_parameter_pair(TreeTraversalMode::Enter, self);
836        let children_ret = if ret == Ok(TraversalResult::Continue) {
837            self.identifier_with_type.visit(emitter)
838        } else {
839            ret
840        };
841        match children_ret? {
842            TraversalResult::Continue => emitter.emit_parameter_pair(TreeTraversalMode::Exit, self),
843            _ => Ok(TraversalResult::Continue),
844        }
845    }
846}
847
848impl AstVisitor for NodeComponentBody {
849    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
850        let ret = emitter.emit_component_body(TreeTraversalMode::Enter, self);
851        let children_ret = if ret == Ok(TraversalResult::Continue) {
852            if let Some(statement_block) = &self.statement_block {
853                statement_block.visit(emitter)
854            } else {
855                Ok(TraversalResult::Continue)
856            }
857        } else {
858            ret
859        };
860        match children_ret? {
861            TraversalResult::Continue => emitter.emit_component_body(TreeTraversalMode::Exit, self),
862            _ => Ok(TraversalResult::Continue),
863        }
864    }
865}
866
867impl AstVisitor for NodeStatementBlock {
868    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
869        let ret = emitter.emit_statement_block(TreeTraversalMode::Enter, self);
870        // Visit each statement if not skipping children
871        let children_ret = if ret == Ok(TraversalResult::Continue) {
872            for statement in &self.statements {
873                statement.visit(emitter)?;
874            }
875            Ok(TraversalResult::Continue)
876        } else {
877            ret
878        };
879        match children_ret? {
880            TraversalResult::Continue => {
881                emitter.emit_statement_block(TreeTraversalMode::Exit, self)
882            }
883            _ => Ok(TraversalResult::Continue),
884        }
885    }
886}
887
888impl AstVisitor for NodeTypedIdentifier {
889    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
890        let ret = emitter.emit_typed_identifier(TreeTraversalMode::Enter, self);
891        // Visit the annotation child node if the enter phase didn't fail or skip children
892        let children_ret = if ret == Ok(TraversalResult::Continue) {
893            self.annotation.visit(emitter)
894        } else {
895            ret
896        };
897        // Depending on the result of the children's visits, either fail or finish with the exit phase
898        match children_ret? {
899            TraversalResult::Continue => {
900                emitter.emit_typed_identifier(TreeTraversalMode::Exit, self)
901            }
902            _ => Ok(TraversalResult::Continue),
903        }
904    }
905}
906
907impl AstVisitor for NodeTypeAnnotation {
908    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
909        let ret = emitter.emit_type_annotation(TreeTraversalMode::Enter, self);
910        // Child element: self.type_name
911        let children_ret = if ret == Ok(TraversalResult::Continue) {
912            self.type_name.visit(emitter)
913        } else {
914            ret
915        };
916        match children_ret? {
917            TraversalResult::Continue => {
918                emitter.emit_type_annotation(TreeTraversalMode::Exit, self)
919            }
920            _ => Ok(TraversalResult::Continue),
921        }
922    }
923}
924
925impl AstVisitor for NodeProgram {
926    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
927        // Emit enter event
928        let ret = emitter.emit_program(TreeTraversalMode::Enter, self);
929        let children_ret = if ret == Ok(TraversalResult::Continue) {
930            // Visit import_declarations if it's not None
931            if let Some(import_declarations) = &self.import_declarations {
932                let result = import_declarations.visit(emitter);
933
934                if result != Ok(TraversalResult::Continue) {
935                    return result;
936                }
937            }
938            // Visit library_definition if it's not None
939            if let Some(library_definition) = &self.library_definition {
940                let result = library_definition.visit(emitter);
941
942                if result != Ok(TraversalResult::Continue) {
943                    return result;
944                }
945            }
946            // Visit contract_definition
947
948            self.contract_definition.visit(emitter)
949        } else {
950            ret
951        };
952        // Emit exit event
953        match children_ret? {
954            TraversalResult::Continue => emitter.emit_program(TreeTraversalMode::Exit, self),
955            _ => Ok(TraversalResult::Continue),
956        }
957    }
958}
959
960impl AstVisitor for NodeLibraryDefinition {
961    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
962        let ret = emitter.emit_library_definition(TreeTraversalMode::Enter, self);
963        let children_ret = if ret == Ok(TraversalResult::Continue) {
964            for definition in &self.definitions {
965                let result = definition.visit(emitter);
966
967                match result {
968                    Err(msg) => return Err(msg),
969                    _ => continue,
970                };
971            }
972            Ok(TraversalResult::Continue)
973        } else {
974            ret
975        };
976        match children_ret? {
977            TraversalResult::Continue => {
978                emitter.emit_library_definition(TreeTraversalMode::Exit, self)
979            }
980            _ => Ok(TraversalResult::Continue),
981        }
982    }
983}
984impl AstVisitor for NodeLibrarySingleDefinition {
985    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
986        let ret = emitter.emit_library_single_definition(TreeTraversalMode::Enter, self);
987        let children_ret = if ret == Ok(TraversalResult::Continue) {
988            match self {
989                NodeLibrarySingleDefinition::LetDefinition {
990                    variable_name: _,
991                    type_annotation: _,
992                    expression,
993                } => {
994                    // TODO: Unused variables aboce
995                    let _ = expression.visit(emitter)?;
996
997                    unimplemented!()
998                }
999                NodeLibrarySingleDefinition::TypeDefinition(name, option_clause) => {
1000                    let result = name.visit(emitter);
1001
1002                    match result {
1003                        Err(msg) => Err(msg),
1004                        _ => match option_clause {
1005                            Some(clauses) => {
1006                                for clause in clauses {
1007                                    clause.visit(emitter)?;
1008                                }
1009                                Ok(TraversalResult::Continue)
1010                            }
1011                            None => Ok(TraversalResult::Continue),
1012                        },
1013                    }
1014                }
1015            }
1016        } else {
1017            ret
1018        };
1019        match children_ret? {
1020            TraversalResult::Continue => {
1021                emitter.emit_library_single_definition(TreeTraversalMode::Exit, self)
1022            }
1023            _ => Ok(TraversalResult::Continue),
1024        }
1025    }
1026}
1027impl AstVisitor for NodeContractDefinition {
1028    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1029        let ret = emitter.emit_contract_definition(TreeTraversalMode::Enter, self);
1030        let children_ret = if ret == Ok(TraversalResult::Continue) {
1031            self.parameters.visit(emitter)?;
1032
1033            if let Some(constraint) = &self.constraint {
1034                constraint.visit(emitter)?;
1035            }
1036
1037            for field in &self.fields {
1038                field.visit(emitter)?;
1039            }
1040
1041            for component in &self.components {
1042                component.visit(emitter)?;
1043            }
1044
1045            Ok(TraversalResult::Continue)
1046        } else {
1047            ret
1048        };
1049        match children_ret? {
1050            TraversalResult::Continue => {
1051                emitter.emit_contract_definition(TreeTraversalMode::Exit, self)
1052            }
1053            _ => Ok(TraversalResult::Continue),
1054        }
1055    }
1056}
1057
1058impl AstVisitor for NodeContractField {
1059    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1060        let ret = emitter.emit_contract_field(TreeTraversalMode::Enter, self);
1061        let children_ret = if ret == Ok(TraversalResult::Continue) {
1062            match self.typed_identifier.visit(emitter) {
1063                Err(msg) => Err(msg),
1064                _ => self.right_hand_side.visit(emitter),
1065            }
1066        } else {
1067            ret
1068        };
1069        match children_ret? {
1070            TraversalResult::Continue => emitter.emit_contract_field(TreeTraversalMode::Exit, self),
1071            _ => Ok(TraversalResult::Continue),
1072        }
1073    }
1074}
1075impl AstVisitor for NodeWithConstraint {
1076    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1077        let ret = emitter.emit_with_constraint(TreeTraversalMode::Enter, self);
1078        let children_ret = if ret == Ok(TraversalResult::Continue) {
1079            self.expression.visit(emitter)
1080        } else {
1081            ret
1082        };
1083        match children_ret? {
1084            TraversalResult::Continue => {
1085                emitter.emit_with_constraint(TreeTraversalMode::Exit, self)
1086            }
1087            _ => Ok(TraversalResult::Continue),
1088        }
1089    }
1090}
1091impl AstVisitor for NodeComponentDefinition {
1092    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1093        let ret = emitter.emit_component_definition(TreeTraversalMode::Enter, self);
1094        let children_ret = if ret == Ok(TraversalResult::Continue) {
1095            match self {
1096                NodeComponentDefinition::TransitionComponent(transition_definition) => {
1097                    transition_definition.visit(emitter)
1098                }
1099                NodeComponentDefinition::ProcedureComponent(procedure_definition) => {
1100                    procedure_definition.visit(emitter)
1101                }
1102            }
1103        } else {
1104            ret
1105        };
1106        match children_ret? {
1107            TraversalResult::Continue => {
1108                emitter.emit_component_definition(TreeTraversalMode::Exit, self)
1109            }
1110            _ => Ok(TraversalResult::Continue),
1111        }
1112    }
1113}
1114impl AstVisitor for NodeProcedureDefinition {
1115    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1116        let ret = emitter.emit_procedure_definition(TreeTraversalMode::Enter, self);
1117        let children_ret = if ret == Ok(TraversalResult::Continue) {
1118            let result = self.name.visit(emitter);
1119            match result {
1120                Err(msg) => Err(msg),
1121                _ => match self.parameters.visit(emitter) {
1122                    Err(msg) => Err(msg),
1123                    _ => self.body.visit(emitter),
1124                },
1125            }
1126        } else {
1127            ret
1128        };
1129        match children_ret? {
1130            TraversalResult::Continue => {
1131                emitter.emit_procedure_definition(TreeTraversalMode::Exit, self)
1132            }
1133            _ => Ok(TraversalResult::Continue),
1134        }
1135    }
1136}
1137impl AstVisitor for NodeTransitionDefinition {
1138    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1139        let ret = emitter.emit_transition_definition(TreeTraversalMode::Enter, self);
1140        let children_ret = if ret == Ok(TraversalResult::Continue) {
1141            self.name.visit(emitter)?;
1142            self.parameters.visit(emitter)?;
1143            self.body.visit(emitter)
1144        } else {
1145            ret
1146        };
1147        match children_ret? {
1148            TraversalResult::Continue => {
1149                emitter.emit_transition_definition(TreeTraversalMode::Exit, self)
1150            }
1151            _ => Ok(TraversalResult::Continue),
1152        }
1153    }
1154}
1155
1156impl AstVisitor for NodeTypeAlternativeClause {
1157    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1158        match emitter.emit_type_alternative_clause(TreeTraversalMode::Enter, self)? {
1159            TraversalResult::SkipChildren => return Ok(TraversalResult::Continue),
1160            TraversalResult::Continue => (),
1161        }
1162        let children_ret = match self {
1163            NodeTypeAlternativeClause::ClauseType(type_name) => type_name.visit(emitter),
1164            NodeTypeAlternativeClause::ClauseTypeWithArgs(type_name, type_args) => {
1165                type_name.visit(emitter)?;
1166
1167                for type_arg in type_args {
1168                    type_arg.visit(emitter)?;
1169                }
1170
1171                Ok(TraversalResult::Continue)
1172            }
1173        };
1174        match children_ret? {
1175            TraversalResult::Continue => {
1176                emitter.emit_type_alternative_clause(TreeTraversalMode::Exit, self)
1177            }
1178            _ => Ok(TraversalResult::Continue),
1179        }
1180    }
1181}
1182
1183impl AstVisitor for NodeTypeMapValueArguments {
1184    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1185        let ret = emitter.emit_type_map_value_arguments(TreeTraversalMode::Enter, self);
1186        let children_ret = if ret == Ok(TraversalResult::Continue) {
1187            match self {
1188                NodeTypeMapValueArguments::EnclosedTypeMapValue(enclosed) => {
1189                    enclosed.visit(emitter)
1190                }
1191                NodeTypeMapValueArguments::GenericMapValueArgument(meta_identifier) => {
1192                    meta_identifier.visit(emitter)
1193                }
1194                NodeTypeMapValueArguments::MapKeyValueType(key_type, value_type) => {
1195                    match key_type.visit(emitter) {
1196                        Err(msg) => Err(msg),
1197                        _ => value_type.visit(emitter),
1198                    }
1199                }
1200            }
1201        } else {
1202            ret
1203        };
1204        match children_ret? {
1205            TraversalResult::Continue => {
1206                emitter.emit_type_map_value_arguments(TreeTraversalMode::Exit, self)
1207            }
1208            _ => Ok(TraversalResult::Continue),
1209        }
1210    }
1211}
1212
1213impl AstVisitor for NodeTypeMapValueAllowingTypeArguments {
1214    fn visit(&self, emitter: &mut dyn AstConverting) -> Result<TraversalResult, String> {
1215        let ret =
1216            emitter.emit_type_map_value_allowing_type_arguments(TreeTraversalMode::Enter, self);
1217        let children_ret = if ret == Ok(TraversalResult::Continue) {
1218            match self {
1219                NodeTypeMapValueAllowingTypeArguments::TypeMapValueNoArgs(type_map_value) => {
1220                    type_map_value.visit(emitter)
1221                }
1222                NodeTypeMapValueAllowingTypeArguments::TypeMapValueWithArgs(
1223                    meta_id,
1224                    value_args,
1225                ) => {
1226                    let mut ret = meta_id.visit(emitter);
1227
1228                    if ret == Ok(TraversalResult::Continue) {
1229                        for value_arg in value_args {
1230                            ret = value_arg.visit(emitter);
1231                            if ret != Ok(TraversalResult::Continue) {
1232                                break;
1233                            }
1234                        }
1235                    }
1236
1237                    ret
1238                }
1239            }
1240        } else {
1241            ret
1242        }?;
1243        match children_ret {
1244            TraversalResult::Continue => {
1245                emitter.emit_type_map_value_allowing_type_arguments(TreeTraversalMode::Exit, self)
1246            }
1247            _ => Ok(TraversalResult::Continue),
1248        }
1249    }
1250}