neo_solidity/solidity/analyse/modifiers/
expand.rs1fn build_modifier_definition_map(
2 contract: &ContractIR,
3) -> std::collections::HashMap<(String, usize), FunctionIR> {
4 let mut map = std::collections::HashMap::new();
5 for func in &contract.functions {
6 if matches!(func.ty, FunctionTy::Modifier) {
7 map.insert((func.name.clone(), func.parameters.len()), func.clone());
8 }
9 }
10 map
11}
12
13fn apply_modifier_calls_to_body(
14 original_body: &Statement,
15 modifier_calls: &[Base],
16 modifier_defs: &std::collections::HashMap<(String, usize), FunctionIR>,
17) -> Result<Statement, SolidityError> {
18 let mut current = original_body.clone();
19
20 for modifier_call in modifier_calls.iter().rev() {
21 let Some(name) = base_last_name(modifier_call) else {
22 continue;
23 };
24 let arg_list: Vec<Expression> = modifier_call.args.clone().unwrap_or_default();
25 let key = (name.clone(), arg_list.len());
26 let Some(modifier_def) = modifier_defs.get(&key) else {
27 return Err(SolidityError::Analysis(format!(
28 "unresolved modifier '{name}' with {} argument(s)",
29 arg_list.len()
30 )));
31 };
32
33 let Some(modifier_body) = modifier_def.body.as_ref() else {
34 return Err(SolidityError::Analysis(format!(
35 "modifier '{name}' has no body"
36 )));
37 };
38
39 let substitutions = build_parameter_substitutions(&modifier_def.parameters, &arg_list)?;
40 current = rewrite_statement(modifier_body, &substitutions, Some(¤t));
41 }
42
43 Ok(current)
44}
45
46fn statement_list_from_body(body: &Statement) -> Vec<Statement> {
47 match body {
48 Statement::Block { statements, .. } => statements.clone(),
49 stmt => vec![stmt.clone()],
50 }
51}