forge/mutation/mutators/
elim_delegate_mutator.rs1use std::fmt::Display;
2
3use eyre::Result;
4use solar::ast::ExprKind;
5
6use super::{MutationContext, Mutator};
7
8use crate::mutation::mutant::{Mutant, MutationType};
9
10pub struct ElimDelegateMutator;
11
12impl Mutator for ElimDelegateMutator {
13 fn generate_mutants(&self, context: &MutationContext<'_>) -> Result<Vec<Mutant>> {
14 let ident_span = context
18 .expr
19 .as_ref()
20 .and_then(|expr| match &expr.kind {
21 ExprKind::Call(callee, _) => Some(callee),
22 _ => None,
23 })
24 .and_then(|callee| match &callee.kind {
25 ExprKind::Member(_, ident) => Some(ident.span),
26 _ => None,
27 })
28 .unwrap_or(context.span);
29
30 Ok(vec![Mutant {
31 span: ident_span,
32 mutation: MutationType::ElimDelegate,
33 path: context.path.clone(),
34 original: "delegatecall".to_string(),
37 source_line: context.source_line(),
38 line_number: context.line_number(),
39 column_number: context.column_number(),
40 }])
41 }
42
43 fn is_applicable(&self, ctxt: &MutationContext<'_>) -> bool {
44 ctxt.expr
45 .as_ref()
46 .and_then(|expr| match &expr.kind {
47 ExprKind::Call(callee, _) => Some(callee),
48 _ => None,
49 })
50 .and_then(|callee| match &callee.kind {
51 ExprKind::Member(_, ident) => Some(ident),
52 _ => None,
53 })
54 .is_some_and(|ident| ident.to_string() == "delegatecall")
55 }
56}
57
58impl Display for ElimDelegateMutator {
59 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60 write!(f, "")
61 }
62}