use ryo_mutations::debugger::{DbgWrapMutation, InsertInspectMutation, RemoveDebugLogsMutation};
use ryo_mutations::MutationResult;
use ryo_source::pure::PureItem;
use ryo_symbol::SymbolKind;
use crate::engine::{ASTMutationContext, ASTRegApply};
impl ASTRegApply for DbgWrapMutation {
fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
let mut total_changes = 0;
let fn_ids: Vec<_> = ctx
.symbol_registry
.iter()
.filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Function))
.map(|(id, _)| id)
.collect();
for fn_id in fn_ids {
if let Some(PureItem::Fn(func)) = ctx.ast_registry.get(fn_id) {
let (new_func, count) = self.transform_fn(func);
if count > 0 {
ctx.set_ast(fn_id, PureItem::Fn(new_func));
total_changes += count;
}
}
}
let impl_ids: Vec<_> = ctx
.symbol_registry
.iter()
.filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Impl))
.map(|(id, _)| id)
.collect();
for impl_id in impl_ids {
if let Some(PureItem::Impl(imp)) = ctx.ast_registry.get(impl_id) {
let mut new_impl = imp.clone();
let mut impl_changes = 0;
for impl_item in &mut new_impl.items {
if let ryo_source::pure::PureImplItem::Fn(method) = impl_item {
let (new_method, count) = self.transform_fn(method);
if count > 0 {
*method = new_method;
impl_changes += count;
}
}
}
if impl_changes > 0 {
ctx.set_ast(impl_id, PureItem::Impl(new_impl));
total_changes += impl_changes;
}
}
}
MutationResult {
mutation_type: "DbgWrap".to_string(),
changes: total_changes,
description: if total_changes > 0 {
format!("Wrapped {} expression(s) with dbg!()", total_changes)
} else {
"No expressions wrapped".to_string()
},
}
}
}
impl ASTRegApply for InsertInspectMutation {
fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
let mut total_changes = 0;
let fn_ids: Vec<_> = ctx
.symbol_registry
.iter()
.filter(|(id, path)| {
if ctx.symbol_registry.kind(*id) != Some(SymbolKind::Function) {
return false;
}
if let Some(ref target) = self.in_function {
return path.name() == target;
}
true
})
.map(|(id, _)| id)
.collect();
for fn_id in fn_ids {
if let Some(PureItem::Fn(func)) = ctx.ast_registry.get(fn_id) {
let (new_func, count) = self.transform_fn(func);
if count > 0 {
ctx.set_ast(fn_id, PureItem::Fn(new_func));
total_changes += count;
}
}
}
let impl_ids: Vec<_> = ctx
.symbol_registry
.iter()
.filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Impl))
.map(|(id, _)| id)
.collect();
for impl_id in impl_ids {
if let Some(PureItem::Impl(imp)) = ctx.ast_registry.get(impl_id) {
let mut new_impl = imp.clone();
let mut impl_changes = 0;
for impl_item in &mut new_impl.items {
if let ryo_source::pure::PureImplItem::Fn(method) = impl_item {
if let Some(ref target) = self.in_function {
if &method.name != target {
continue;
}
}
let (new_method, count) = self.transform_fn(method);
if count > 0 {
*method = new_method;
impl_changes += count;
}
}
}
if impl_changes > 0 {
ctx.set_ast(impl_id, PureItem::Impl(new_impl));
total_changes += impl_changes;
}
}
}
MutationResult {
mutation_type: "InsertInspect".to_string(),
changes: total_changes,
description: if total_changes > 0 {
format!("Inserted {} .inspect() call(s)", total_changes)
} else {
"No .inspect() calls inserted".to_string()
},
}
}
}
impl ASTRegApply for RemoveDebugLogsMutation {
fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
let mut total_changes = 0;
let fn_ids: Vec<_> = ctx
.symbol_registry
.iter()
.filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Function))
.map(|(id, _)| id)
.collect();
for fn_id in fn_ids {
if let Some(PureItem::Fn(func)) = ctx.ast_registry.get(fn_id) {
let (new_func, count) = self.transform_fn(func);
if count > 0 {
ctx.set_ast(fn_id, PureItem::Fn(new_func));
total_changes += count;
}
}
}
let impl_ids: Vec<_> = ctx
.symbol_registry
.iter()
.filter(|(id, _)| ctx.symbol_registry.kind(*id) == Some(SymbolKind::Impl))
.map(|(id, _)| id)
.collect();
for impl_id in impl_ids {
if let Some(PureItem::Impl(imp)) = ctx.ast_registry.get(impl_id) {
let mut new_impl = imp.clone();
let mut impl_changes = 0;
for impl_item in &mut new_impl.items {
if let ryo_source::pure::PureImplItem::Fn(method) = impl_item {
let (new_method, count) = self.transform_fn(method);
if count > 0 {
*method = new_method;
impl_changes += count;
}
}
}
if impl_changes > 0 {
ctx.set_ast(impl_id, PureItem::Impl(new_impl));
total_changes += impl_changes;
}
}
}
MutationResult {
mutation_type: "RemoveDebugLogs".to_string(),
changes: total_changes,
description: if total_changes > 0 {
format!("Removed {} debug log(s)", total_changes)
} else {
"No debug logs removed".to_string()
},
}
}
}