neo-devpack-solidity 0.22.0

Production-focused Solidity-to-NeoVM compilation system
Documentation
fn rewrite_statement(
    stmt: &Statement,
    subs: &std::collections::HashMap<String, Expression>,
    placeholder_body: Option<&Statement>,
) -> Statement {
    if modifier_placeholder_stmt(stmt) {
        if let Some(body) = placeholder_body {
            return body.clone();
        }
    }

    match stmt {
        Statement::Block {
            loc,
            unchecked,
            statements,
        } => Statement::Block {
            loc: *loc,
            unchecked: *unchecked,
            statements: statements
                .iter()
                .map(|s| rewrite_statement(s, subs, placeholder_body))
                .collect(),
        },
        Statement::Assembly { .. } => stmt.clone(),
        Statement::Args(loc, args) => {
            let rewritten_args: Vec<NamedArgument> = args
                .iter()
                .map(|arg| NamedArgument {
                    loc: arg.loc,
                    name: arg.name.clone(),
                    expr: rewrite_expression(&arg.expr, subs),
                })
                .collect();
            Statement::Args(*loc, rewritten_args)
        }
        Statement::If(loc, cond, then_stmt, else_stmt) => Statement::If(
            *loc,
            rewrite_expression(cond, subs),
            Box::new(rewrite_statement(then_stmt, subs, placeholder_body)),
            else_stmt
                .as_ref()
                .map(|s| Box::new(rewrite_statement(s, subs, placeholder_body))),
        ),
        Statement::While(loc, cond, body) => Statement::While(
            *loc,
            rewrite_expression(cond, subs),
            Box::new(rewrite_statement(body, subs, placeholder_body)),
        ),
        Statement::Expression(loc, expr) => {
            Statement::Expression(*loc, rewrite_expression(expr, subs))
        }
        Statement::VariableDefinition(loc, decl, init) => Statement::VariableDefinition(
            *loc,
            decl.clone(),
            init.as_ref().map(|e| rewrite_expression(e, subs)),
        ),
        Statement::For(loc, init, cond, next, body) => Statement::For(
            *loc,
            init.as_ref()
                .map(|s| Box::new(rewrite_statement(s, subs, placeholder_body))),
            cond.as_ref().map(|e| Box::new(rewrite_expression(e, subs))),
            next.as_ref().map(|e| Box::new(rewrite_expression(e, subs))),
            body.as_ref()
                .map(|s| Box::new(rewrite_statement(s, subs, placeholder_body))),
        ),
        Statement::DoWhile(loc, body, cond) => Statement::DoWhile(
            *loc,
            Box::new(rewrite_statement(body, subs, placeholder_body)),
            rewrite_expression(cond, subs),
        ),
        Statement::Continue(_) | Statement::Break(_) => stmt.clone(),
        Statement::Return(loc, expr) => {
            Statement::Return(*loc, expr.as_ref().map(|e| rewrite_expression(e, subs)))
        }
        Statement::Revert(loc, path, args) => Statement::Revert(
            *loc,
            path.clone(),
            args.iter().map(|e| rewrite_expression(e, subs)).collect(),
        ),
        Statement::RevertNamedArgs(loc, path, args) => {
            let rewritten_args: Vec<NamedArgument> = args
                .iter()
                .map(|arg| NamedArgument {
                    loc: arg.loc,
                    name: arg.name.clone(),
                    expr: rewrite_expression(&arg.expr, subs),
                })
                .collect();
            Statement::RevertNamedArgs(*loc, path.clone(), rewritten_args)
        }
        Statement::Emit(loc, expr) => Statement::Emit(*loc, rewrite_expression(expr, subs)),
        Statement::Try(loc, expr, handler, catches) => Statement::Try(
            *loc,
            rewrite_expression(expr, subs),
            handler.as_ref().map(|(params, stmt)| {
                (
                    params.clone(),
                    Box::new(rewrite_statement(stmt, subs, placeholder_body)),
                )
            }),
            catches
                .iter()
                .map(|clause| match clause {
                    CatchClause::Simple(loc, param, stmt) => CatchClause::Simple(
                        *loc,
                        param.clone(),
                        rewrite_statement(stmt, subs, placeholder_body),
                    ),
                    CatchClause::Named(loc, path, param, stmt) => CatchClause::Named(
                        *loc,
                        path.clone(),
                        param.clone(),
                        rewrite_statement(stmt, subs, placeholder_body),
                    ),
                })
                .collect(),
        ),
        Statement::Error(_) => stmt.clone(),
    }
}