ryo_executor/engine/impls/
debugger.rs1use ryo_mutations::debugger::{DbgWrapMutation, InsertInspectMutation, RemoveDebugLogsMutation};
11use ryo_mutations::MutationResult;
12use ryo_source::pure::PureItem;
13use ryo_symbol::SymbolKind;
14
15use crate::engine::{ASTMutationContext, ASTRegApply};
16
17impl ASTRegApply for DbgWrapMutation {
18 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
19 let mut total_changes = 0;
20
21 let fn_ids: Vec<_> = ctx
23 .symbol_registry
24 .iter()
25 .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Function))
26 .map(|(id, _)| id)
27 .collect();
28
29 for fn_id in fn_ids {
30 if let Some(PureItem::Fn(func)) = ctx.ast_registry.get(fn_id) {
31 let (new_func, count) = self.transform_fn(func);
32 if count > 0 {
33 ctx.set_ast(fn_id, PureItem::Fn(new_func));
34 total_changes += count;
35 }
36 }
37 }
38
39 let impl_ids: Vec<_> = ctx
41 .symbol_registry
42 .iter()
43 .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Impl))
44 .map(|(id, _)| id)
45 .collect();
46
47 for impl_id in impl_ids {
48 if let Some(PureItem::Impl(imp)) = ctx.ast_registry.get(impl_id) {
49 let mut new_impl = imp.clone();
50 let mut impl_changes = 0;
51
52 for impl_item in &mut new_impl.items {
53 if let ryo_source::pure::PureImplItem::Fn(method) = impl_item {
54 let (new_method, count) = self.transform_fn(method);
55 if count > 0 {
56 *method = new_method;
57 impl_changes += count;
58 }
59 }
60 }
61
62 if impl_changes > 0 {
63 ctx.set_ast(impl_id, PureItem::Impl(new_impl));
64 total_changes += impl_changes;
65 }
66 }
67 }
68
69 MutationResult {
70 mutation_type: "DbgWrap".to_string(),
71 changes: total_changes,
72 description: if total_changes > 0 {
73 format!("Wrapped {} expression(s) with dbg!()", total_changes)
74 } else {
75 "No expressions wrapped".to_string()
76 },
77 }
78 }
79}
80
81impl ASTRegApply for InsertInspectMutation {
82 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
83 let mut total_changes = 0;
84
85 let fn_ids: Vec<_> = ctx
87 .symbol_registry
88 .iter()
89 .filter(|(id, path)| {
90 if ctx.symbol_registry.kind(*id) != Some(SymbolKind::Function) {
91 return false;
92 }
93 if let Some(ref target) = self.in_function {
95 return path.name() == target;
96 }
97 true
98 })
99 .map(|(id, _)| id)
100 .collect();
101
102 for fn_id in fn_ids {
103 if let Some(PureItem::Fn(func)) = ctx.ast_registry.get(fn_id) {
104 let (new_func, count) = self.transform_fn(func);
105 if count > 0 {
106 ctx.set_ast(fn_id, PureItem::Fn(new_func));
107 total_changes += count;
108 }
109 }
110 }
111
112 let impl_ids: Vec<_> = ctx
114 .symbol_registry
115 .iter()
116 .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Impl))
117 .map(|(id, _)| id)
118 .collect();
119
120 for impl_id in impl_ids {
121 if let Some(PureItem::Impl(imp)) = ctx.ast_registry.get(impl_id) {
122 let mut new_impl = imp.clone();
123 let mut impl_changes = 0;
124
125 for impl_item in &mut new_impl.items {
126 if let ryo_source::pure::PureImplItem::Fn(method) = impl_item {
127 if let Some(ref target) = self.in_function {
129 if &method.name != target {
130 continue;
131 }
132 }
133
134 let (new_method, count) = self.transform_fn(method);
135 if count > 0 {
136 *method = new_method;
137 impl_changes += count;
138 }
139 }
140 }
141
142 if impl_changes > 0 {
143 ctx.set_ast(impl_id, PureItem::Impl(new_impl));
144 total_changes += impl_changes;
145 }
146 }
147 }
148
149 MutationResult {
150 mutation_type: "InsertInspect".to_string(),
151 changes: total_changes,
152 description: if total_changes > 0 {
153 format!("Inserted {} .inspect() call(s)", total_changes)
154 } else {
155 "No .inspect() calls inserted".to_string()
156 },
157 }
158 }
159}
160
161impl ASTRegApply for RemoveDebugLogsMutation {
162 fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
163 let mut total_changes = 0;
164
165 let fn_ids: Vec<_> = ctx
167 .symbol_registry
168 .iter()
169 .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Function))
170 .map(|(id, _)| id)
171 .collect();
172
173 for fn_id in fn_ids {
174 if let Some(PureItem::Fn(func)) = ctx.ast_registry.get(fn_id) {
175 let (new_func, count) = self.transform_fn(func);
176 if count > 0 {
177 ctx.set_ast(fn_id, PureItem::Fn(new_func));
178 total_changes += count;
179 }
180 }
181 }
182
183 let impl_ids: Vec<_> = ctx
185 .symbol_registry
186 .iter()
187 .filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Impl))
188 .map(|(id, _)| id)
189 .collect();
190
191 for impl_id in impl_ids {
192 if let Some(PureItem::Impl(imp)) = ctx.ast_registry.get(impl_id) {
193 let mut new_impl = imp.clone();
194 let mut impl_changes = 0;
195
196 for impl_item in &mut new_impl.items {
197 if let ryo_source::pure::PureImplItem::Fn(method) = impl_item {
198 let (new_method, count) = self.transform_fn(method);
199 if count > 0 {
200 *method = new_method;
201 impl_changes += count;
202 }
203 }
204 }
205
206 if impl_changes > 0 {
207 ctx.set_ast(impl_id, PureItem::Impl(new_impl));
208 total_changes += impl_changes;
209 }
210 }
211 }
212
213 MutationResult {
214 mutation_type: "RemoveDebugLogs".to_string(),
215 changes: total_changes,
216 description: if total_changes > 0 {
217 format!("Removed {} debug log(s)", total_changes)
218 } else {
219 "No debug logs removed".to_string()
220 },
221 }
222 }
223}