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}