neo_solidity/solidity/analyse/modifiers/rewrite/
statements.rs

1fn rewrite_statement(
2    stmt: &Statement,
3    subs: &std::collections::HashMap<String, Expression>,
4    placeholder_body: Option<&Statement>,
5) -> Statement {
6    if modifier_placeholder_stmt(stmt) {
7        if let Some(body) = placeholder_body {
8            return body.clone();
9        }
10    }
11
12    match stmt {
13        Statement::Block {
14            loc,
15            unchecked,
16            statements,
17        } => Statement::Block {
18            loc: *loc,
19            unchecked: *unchecked,
20            statements: statements
21                .iter()
22                .map(|s| rewrite_statement(s, subs, placeholder_body))
23                .collect(),
24        },
25        Statement::Assembly { .. } => stmt.clone(),
26        Statement::Args(loc, args) => {
27            let rewritten_args: Vec<NamedArgument> = args
28                .iter()
29                .map(|arg| NamedArgument {
30                    loc: arg.loc,
31                    name: arg.name.clone(),
32                    expr: rewrite_expression(&arg.expr, subs),
33                })
34                .collect();
35            Statement::Args(*loc, rewritten_args)
36        }
37        Statement::If(loc, cond, then_stmt, else_stmt) => Statement::If(
38            *loc,
39            rewrite_expression(cond, subs),
40            Box::new(rewrite_statement(then_stmt, subs, placeholder_body)),
41            else_stmt
42                .as_ref()
43                .map(|s| Box::new(rewrite_statement(s, subs, placeholder_body))),
44        ),
45        Statement::While(loc, cond, body) => Statement::While(
46            *loc,
47            rewrite_expression(cond, subs),
48            Box::new(rewrite_statement(body, subs, placeholder_body)),
49        ),
50        Statement::Expression(loc, expr) => {
51            Statement::Expression(*loc, rewrite_expression(expr, subs))
52        }
53        Statement::VariableDefinition(loc, decl, init) => Statement::VariableDefinition(
54            *loc,
55            decl.clone(),
56            init.as_ref().map(|e| rewrite_expression(e, subs)),
57        ),
58        Statement::For(loc, init, cond, next, body) => Statement::For(
59            *loc,
60            init.as_ref()
61                .map(|s| Box::new(rewrite_statement(s, subs, placeholder_body))),
62            cond.as_ref().map(|e| Box::new(rewrite_expression(e, subs))),
63            next.as_ref().map(|e| Box::new(rewrite_expression(e, subs))),
64            body.as_ref()
65                .map(|s| Box::new(rewrite_statement(s, subs, placeholder_body))),
66        ),
67        Statement::DoWhile(loc, body, cond) => Statement::DoWhile(
68            *loc,
69            Box::new(rewrite_statement(body, subs, placeholder_body)),
70            rewrite_expression(cond, subs),
71        ),
72        Statement::Continue(_) | Statement::Break(_) => stmt.clone(),
73        Statement::Return(loc, expr) => {
74            Statement::Return(*loc, expr.as_ref().map(|e| rewrite_expression(e, subs)))
75        }
76        Statement::Revert(loc, path, args) => Statement::Revert(
77            *loc,
78            path.clone(),
79            args.iter().map(|e| rewrite_expression(e, subs)).collect(),
80        ),
81        Statement::RevertNamedArgs(loc, path, args) => {
82            let rewritten_args: Vec<NamedArgument> = args
83                .iter()
84                .map(|arg| NamedArgument {
85                    loc: arg.loc,
86                    name: arg.name.clone(),
87                    expr: rewrite_expression(&arg.expr, subs),
88                })
89                .collect();
90            Statement::RevertNamedArgs(*loc, path.clone(), rewritten_args)
91        }
92        Statement::Emit(loc, expr) => Statement::Emit(*loc, rewrite_expression(expr, subs)),
93        Statement::Try(loc, expr, handler, catches) => Statement::Try(
94            *loc,
95            rewrite_expression(expr, subs),
96            handler.as_ref().map(|(params, stmt)| {
97                (
98                    params.clone(),
99                    Box::new(rewrite_statement(stmt, subs, placeholder_body)),
100                )
101            }),
102            catches
103                .iter()
104                .map(|clause| match clause {
105                    CatchClause::Simple(loc, param, stmt) => CatchClause::Simple(
106                        *loc,
107                        param.clone(),
108                        rewrite_statement(stmt, subs, placeholder_body),
109                    ),
110                    CatchClause::Named(loc, path, param, stmt) => CatchClause::Named(
111                        *loc,
112                        path.clone(),
113                        param.clone(),
114                        rewrite_statement(stmt, subs, placeholder_body),
115                    ),
116                })
117                .collect(),
118        ),
119        Statement::Error(_) => stmt.clone(),
120    }
121}