leo_passes/static_analysis/
expression.rs1use super::StaticAnalyzingVisitor;
18
19use leo_ast::*;
20
21impl ExpressionVisitor for StaticAnalyzingVisitor<'_> {
22 type AdditionalInput = ();
23 type Output = ();
24
25 fn visit_associated_function(
26 &mut self,
27 input: &AssociatedFunctionExpression,
28 _additional: &Self::AdditionalInput,
29 ) -> Self::Output {
30 let Some(core_function) = CoreFunction::from_symbols(input.variant.name, input.name.name) else {
32 panic!("Typechecking guarantees that this function exists.");
33 };
34
35 if core_function == CoreFunction::FutureAwait {
37 self.assert_future_await(&input.arguments.first(), input.span());
38 }
39 }
40
41 fn visit_call(&mut self, input: &CallExpression, _: &Self::AdditionalInput) -> Self::Output {
42 let caller_program = self.current_program;
43 let callee_program = input.program.unwrap_or(caller_program);
44
45 if self.non_async_external_call_seen
48 && self.variant == Some(Variant::AsyncTransition)
49 && callee_program != caller_program
50 {
51 self.assert_simple_async_transition_call(callee_program, input.function.name, input.span());
52 }
53
54 let function_program = input.program.unwrap_or(self.current_program);
56
57 let func_symbol = self
58 .state
59 .symbol_table
60 .lookup_function(Location::new(function_program, input.function.name))
61 .expect("Type checking guarantees functions exist.");
62
63 if func_symbol.function.variant == Variant::Transition {
64 self.non_async_external_call_seen = true;
65 }
66 }
67}