-
Notifications
You must be signed in to change notification settings - Fork 16
/
Copy pathfunction_traverser.py
402 lines (321 loc) · 12.8 KB
/
function_traverser.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
import typing
import puya.awst.visitors
from puya.awst import nodes as awst_nodes
class FunctionTraverser(
puya.awst.visitors.ExpressionVisitor[None],
puya.awst.visitors.StatementVisitor[None],
):
@typing.override
def visit_assignment_statement(self, statement: awst_nodes.AssignmentStatement) -> None:
statement.target.accept(self)
statement.value.accept(self)
@typing.override
def visit_copy(self, expr: awst_nodes.Copy) -> None:
expr.value.accept(self)
@typing.override
def visit_goto(self, statement: awst_nodes.Goto) -> None:
pass
@typing.override
def visit_assignment_expression(self, expr: awst_nodes.AssignmentExpression) -> None:
expr.target.accept(self)
expr.value.accept(self)
@typing.override
def visit_uint64_binary_operation(self, expr: awst_nodes.UInt64BinaryOperation) -> None:
expr.left.accept(self)
expr.right.accept(self)
@typing.override
def visit_biguint_binary_operation(self, expr: awst_nodes.BigUIntBinaryOperation) -> None:
expr.left.accept(self)
expr.right.accept(self)
@typing.override
def visit_reversed(self, expr: awst_nodes.Reversed) -> None:
if isinstance(expr.expr, awst_nodes.Expression):
expr.expr.accept(self)
@typing.override
def visit_integer_constant(self, expr: awst_nodes.IntegerConstant) -> None:
pass
@typing.override
def visit_decimal_constant(self, expr: awst_nodes.DecimalConstant) -> None:
pass
@typing.override
def visit_bool_constant(self, expr: awst_nodes.BoolConstant) -> None:
pass
@typing.override
def visit_bytes_constant(self, expr: awst_nodes.BytesConstant) -> None:
pass
@typing.override
def visit_string_constant(self, expr: awst_nodes.StringConstant) -> None:
pass
@typing.override
def visit_void_constant(self, expr: awst_nodes.VoidConstant) -> None:
pass
@typing.override
def visit_compiled_contract(self, expr: awst_nodes.CompiledContract) -> None:
for value in expr.template_variables.values():
value.accept(self)
@typing.override
def visit_compiled_logicsig(self, expr: awst_nodes.CompiledLogicSig) -> None:
for value in expr.template_variables.values():
value.accept(self)
@typing.override
def visit_arc4_decode(self, expr: awst_nodes.ARC4Decode) -> None:
expr.value.accept(self)
@typing.override
def visit_arc4_encode(self, expr: awst_nodes.ARC4Encode) -> None:
expr.value.accept(self)
@typing.override
def visit_array_concat(self, expr: awst_nodes.ArrayConcat) -> None:
expr.left.accept(self)
expr.right.accept(self)
@typing.override
def visit_array_pop(self, expr: awst_nodes.ArrayPop) -> None:
expr.base.accept(self)
@typing.override
def visit_array_extend(self, expr: awst_nodes.ArrayExtend) -> None:
expr.base.accept(self)
expr.other.accept(self)
@typing.override
def visit_array_length(self, expr: awst_nodes.ArrayLength) -> None:
expr.array.accept(self)
@typing.override
def visit_array_replace(self, expr: awst_nodes.ArrayReplace) -> None:
expr.base.accept(self)
expr.index.accept(self)
expr.value.accept(self)
@typing.override
def visit_method_constant(self, expr: awst_nodes.MethodConstant) -> None:
pass
@typing.override
def visit_address_constant(self, expr: awst_nodes.AddressConstant) -> None:
pass
@typing.override
def visit_numeric_comparison_expression(
self, expr: awst_nodes.NumericComparisonExpression
) -> None:
expr.lhs.accept(self)
expr.rhs.accept(self)
@typing.override
def visit_var_expression(self, expr: awst_nodes.VarExpression) -> None:
pass
@typing.override
def visit_assert_expression(self, expr: awst_nodes.AssertExpression) -> None:
if expr.condition is not None:
expr.condition.accept(self)
@typing.override
def visit_checked_maybe(self, expr: awst_nodes.CheckedMaybe) -> None:
expr.expr.accept(self)
@typing.override
def visit_intrinsic_call(self, call: awst_nodes.IntrinsicCall) -> None:
for arg in call.stack_args:
arg.accept(self)
@typing.override
def visit_puya_lib_call(self, call: awst_nodes.PuyaLibCall) -> None:
for arg in call.args:
arg.value.accept(self)
@typing.override
def visit_group_transaction_reference(self, ref: awst_nodes.GroupTransactionReference) -> None:
ref.index.accept(self)
@typing.override
def visit_create_inner_transaction(self, call: awst_nodes.CreateInnerTransaction) -> None:
for expr in call.fields.values():
expr.accept(self)
@typing.override
def visit_update_inner_transaction(self, call: awst_nodes.UpdateInnerTransaction) -> None:
call.itxn.accept(self)
for value in call.fields.values():
value.accept(self)
@typing.override
def visit_submit_inner_transaction(self, call: awst_nodes.SubmitInnerTransaction) -> None:
for expr in call.itxns:
expr.accept(self)
@typing.override
def visit_inner_transaction_field(self, itxn_field: awst_nodes.InnerTransactionField) -> None:
itxn_field.itxn.accept(self)
if itxn_field.array_index:
itxn_field.array_index.accept(self)
@typing.override
def visit_tuple_expression(self, expr: awst_nodes.TupleExpression) -> None:
for item in expr.items:
item.accept(self)
@typing.override
def visit_tuple_item_expression(self, expr: awst_nodes.TupleItemExpression) -> None:
expr.base.accept(self)
@typing.override
def visit_field_expression(self, expr: awst_nodes.FieldExpression) -> None:
expr.base.accept(self)
@typing.override
def visit_slice_expression(self, expr: awst_nodes.SliceExpression) -> None:
expr.base.accept(self)
if isinstance(expr.begin_index, awst_nodes.Expression):
expr.begin_index.accept(self)
if isinstance(expr.end_index, awst_nodes.Expression):
expr.end_index.accept(self)
@typing.override
def visit_intersection_slice_expression(
self, expr: awst_nodes.IntersectionSliceExpression
) -> None:
expr.base.accept(self)
if isinstance(expr.begin_index, awst_nodes.Expression):
expr.begin_index.accept(self)
if isinstance(expr.end_index, awst_nodes.Expression):
expr.end_index.accept(self)
@typing.override
def visit_index_expression(self, expr: awst_nodes.IndexExpression) -> None:
expr.base.accept(self)
expr.index.accept(self)
@typing.override
def visit_conditional_expression(self, expr: awst_nodes.ConditionalExpression) -> None:
expr.condition.accept(self)
expr.true_expr.accept(self)
expr.false_expr.accept(self)
@typing.override
def visit_single_evaluation(self, expr: awst_nodes.SingleEvaluation) -> None:
expr.source.accept(self)
@typing.override
def visit_app_state_expression(self, expr: awst_nodes.AppStateExpression) -> None:
expr.key.accept(self)
@typing.override
def visit_app_account_state_expression(
self, expr: awst_nodes.AppAccountStateExpression
) -> None:
expr.key.accept(self)
expr.account.accept(self)
@typing.override
def visit_new_array(self, expr: awst_nodes.NewArray) -> None:
for element in expr.values:
element.accept(self)
@typing.override
def visit_new_struct(self, expr: awst_nodes.NewStruct) -> None:
for element in expr.values.values():
element.accept(self)
@typing.override
def visit_bytes_comparison_expression(
self, expr: awst_nodes.BytesComparisonExpression
) -> None:
expr.lhs.accept(self)
expr.rhs.accept(self)
@typing.override
def visit_subroutine_call_expression(self, expr: awst_nodes.SubroutineCallExpression) -> None:
for arg in expr.args:
arg.value.accept(self)
@typing.override
def visit_bytes_binary_operation(self, expr: awst_nodes.BytesBinaryOperation) -> None:
expr.left.accept(self)
expr.right.accept(self)
@typing.override
def visit_boolean_binary_operation(self, expr: awst_nodes.BooleanBinaryOperation) -> None:
expr.left.accept(self)
expr.right.accept(self)
@typing.override
def visit_uint64_unary_operation(self, expr: awst_nodes.UInt64UnaryOperation) -> None:
expr.expr.accept(self)
@typing.override
def visit_bytes_unary_operation(self, expr: awst_nodes.BytesUnaryOperation) -> None:
expr.expr.accept(self)
@typing.override
def visit_not_expression(self, expr: awst_nodes.Not) -> None:
expr.expr.accept(self)
@typing.override
def visit_block(self, statement: awst_nodes.Block) -> None:
for stmt in statement.body:
stmt.accept(self)
@typing.override
def visit_if_else(self, statement: awst_nodes.IfElse) -> None:
statement.condition.accept(self)
statement.if_branch.accept(self)
if statement.else_branch:
statement.else_branch.accept(self)
@typing.override
def visit_switch(self, statement: awst_nodes.Switch) -> None:
statement.value.accept(self)
for case, block in statement.cases.items():
case.accept(self)
block.accept(self)
if statement.default_case:
statement.default_case.accept(self)
@typing.override
def visit_while_loop(self, statement: awst_nodes.WhileLoop) -> None:
statement.condition.accept(self)
statement.loop_body.accept(self)
@typing.override
def visit_loop_exit(self, statement: awst_nodes.LoopExit) -> None:
pass
@typing.override
def visit_return_statement(self, statement: awst_nodes.ReturnStatement) -> None:
if statement.value is not None:
statement.value.accept(self)
@typing.override
def visit_loop_continue(self, statement: awst_nodes.LoopContinue) -> None:
pass
@typing.override
def visit_expression_statement(self, statement: awst_nodes.ExpressionStatement) -> None:
statement.expr.accept(self)
@typing.override
def visit_template_var(self, statement: awst_nodes.TemplateVar) -> None:
pass
@typing.override
def visit_uint64_augmented_assignment(
self, statement: awst_nodes.UInt64AugmentedAssignment
) -> None:
statement.target.accept(self)
statement.value.accept(self)
@typing.override
def visit_biguint_augmented_assignment(
self, statement: awst_nodes.BigUIntAugmentedAssignment
) -> None:
statement.target.accept(self)
statement.value.accept(self)
@typing.override
def visit_bytes_augmented_assignment(
self, statement: awst_nodes.BytesAugmentedAssignment
) -> None:
statement.target.accept(self)
statement.value.accept(self)
@typing.override
def visit_for_in_loop(self, statement: awst_nodes.ForInLoop) -> None:
statement.sequence.accept(self)
statement.items.accept(self)
statement.loop_body.accept(self)
@typing.override
def visit_reinterpret_cast(self, expr: awst_nodes.ReinterpretCast) -> None:
expr.expr.accept(self)
@typing.override
def visit_enumeration(self, expr: awst_nodes.Enumeration) -> None:
expr.expr.accept(self)
@typing.override
def visit_state_get_ex(self, expr: awst_nodes.StateGetEx) -> None:
expr.field.accept(self)
@typing.override
def visit_state_delete(self, statement: awst_nodes.StateDelete) -> None:
statement.field.accept(self)
@typing.override
def visit_state_get(self, expr: awst_nodes.StateGet) -> None:
expr.field.accept(self)
expr.default.accept(self)
@typing.override
def visit_state_exists(self, expr: awst_nodes.StateExists) -> None:
expr.field.accept(self)
@typing.override
def visit_box_value_expression(self, expr: awst_nodes.BoxValueExpression) -> None:
expr.key.accept(self)
@typing.override
def visit_biguint_postfix_unary_operation(
self, expr: awst_nodes.BigUIntPostfixUnaryOperation
) -> None:
expr.target.accept(self)
@typing.override
def visit_uint64_postfix_unary_operation(
self, expr: awst_nodes.UInt64PostfixUnaryOperation
) -> None:
expr.target.accept(self)
@typing.override
def visit_arc4_router(self, expr: awst_nodes.ARC4Router) -> None:
pass
@typing.override
def visit_range(self, node: awst_nodes.Range) -> None:
node.start.accept(self)
node.stop.accept(self)
node.step.accept(self)
@typing.override
def visit_emit(self, expr: awst_nodes.Emit) -> None:
expr.value.accept(self)