Skip to main content

ryo_mutations/basic/stmt/
replace_expr_at.rs

1//! ReplaceExprAtMutation: Replace expression at a specific position
2//!
3//! Unlike `ReplaceExprMutation` which uses pattern matching, this mutation
4//! replaces an expression at an exact position specified by function SymbolId
5//! and body indices.
6//!
7//! # Example
8//! Function `example` at body indices `[0, 1, 2]` targets:
9//! `body.stmts[0].expr.child[1].child[2]`
10
11use ryo_source::pure::PureExpr;
12use ryo_symbol::SymbolId;
13
14use crate::Mutation;
15
16/// Replace an expression at a specific position using index-based navigation
17#[derive(Debug, Clone)]
18pub struct ReplaceExprAtMutation {
19    /// The target function SymbolId
20    pub target_fn: SymbolId,
21    /// Body indices for navigation (e.g., [0, 1, 2] for stmts[0].child[1].child[2])
22    pub body_indices: Vec<usize>,
23    /// The replacement expression
24    pub new_expr: PureExpr,
25}
26
27impl ReplaceExprAtMutation {
28    /// Create a new position-based replacement mutation
29    pub fn new(target_fn: SymbolId, body_indices: Vec<usize>, new_expr: PureExpr) -> Self {
30        Self {
31            target_fn,
32            body_indices,
33            new_expr,
34        }
35    }
36}
37
38impl Mutation for ReplaceExprAtMutation {
39    fn describe(&self) -> String {
40        format!(
41            "Replace expression at {}::$body::{}",
42            self.target_fn,
43            self.body_indices
44                .iter()
45                .map(|i| i.to_string())
46                .collect::<Vec<_>>()
47                .join("::")
48        )
49    }
50
51    fn mutation_type(&self) -> &'static str {
52        "ReplaceExprAt"
53    }
54
55    fn box_clone(&self) -> Box<dyn Mutation> {
56        Box::new(self.clone())
57    }
58}