Skip to main content

ryo_executor/engine/
ast_reg_apply.rs

1//! ASTRegApply trait - Apply mutations to ASTRegistry
2//!
3//! This trait extends Mutation with registry-based execution capability.
4//! Defined in ryo-executor to avoid circular dependency between
5//! ryo-mutations and ryo-analysis.
6//!
7//! # Design
8//!
9//! ```text
10//! ryo-mutations          ryo-analysis           ryo-executor
11//! ┌──────────────┐      ┌──────────────┐       ┌──────────────┐
12//! │ Mutation     │      │ ASTRegistry  │       │ ASTRegApply  │
13//! │ (base trait) │      │ SymbolReg    │       │ (ext trait)  │
14//! └──────────────┘      └──────────────┘       └──────────────┘
15//!        ↑                     ↑                      │
16//!        └─────────────────────┴──────────────────────┘
17//!                    ASTRegApply: Mutation
18//! ```
19//!
20//! # Quality Policy for V2 Implementations
21//!
22//! When implementing `ASTRegApply` for mutations:
23//!
24//! ## DO:
25//! - Design the implementation to work naturally with ASTRegistry/SymbolRegistry
26//! - Add comprehensive snapshot tests that verify exact output
27//! - Consider if the ASTMutationContext API needs extension for new capabilities
28//!
29//! ## DON'T:
30//! - Create hacky workarounds just to make tests pass
31//! - Use temporary allocations or intermediate representations (defeats V2 purpose)
32//! - Copy V1 patterns that don't fit the registry-based model
33//!
34//! ## When V2 Cannot Handle a Mutation Cleanly:
35//!
36//! If a mutation cannot be implemented cleanly with the current V2 API:
37//!
38//! 1. **Do NOT** hack the implementation or tests to force it to work
39//! 2. **Do** evaluate if ASTMutationContext needs new methods
40//! 3. **Do** consider if ASTRegistry/SymbolRegistry need enhancements
41//! 4. **Do** document the design gap and propose a proper solution
42//!
43//! The goal is a clean, maintainable architecture - not 100% feature coverage
44//! through workarounds.
45//!
46//! # Usage
47//!
48//! ```ignore
49//! use ryo_executor::engine::ASTRegApply;
50//!
51//! impl ASTRegApply for AddFieldMutation {
52//!     fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult {
53//!         // Get target struct from registry
54//!         let id = ctx.lookup(&self.target_path)?;
55//!         let ast = ctx.get_ast_mut(id)?;
56//!
57//!         // Modify AST
58//!         if let PureItem::Struct(s) = ast {
59//!             s.fields.push(new_field);
60//!         }
61//!
62//!         ctx.emit_modified(id, ModificationType::FieldAdded(name));
63//!         MutationResult { ... }
64//!     }
65//! }
66//! ```
67
68use ryo_mutations::{Mutation, MutationResult};
69
70use super::ast_mutation_engine::ASTMutationContext;
71
72/// Trait for mutations that can be applied to ASTRegistry
73///
74/// Extends the base `Mutation` trait with registry-based execution.
75/// This is the primary execution path for the new AST-centric architecture.
76///
77/// # Implementing
78///
79/// Mutations that want to support registry-based execution should:
80/// 1. Implement this trait
81/// 2. Use `ctx.lookup()` to find target symbols
82/// 3. Use `ctx.get_ast_mut()` to modify AST
83/// 4. Use `ctx.emit_*()` to record changes
84///
85/// # Fallback
86///
87/// If a mutation doesn't implement this trait, ASTMutationEngine
88/// will return no changes. The legacy `apply(&mut PureFile)` path
89/// remains available for backward compatibility.
90pub trait ASTRegApply: Mutation {
91    /// Apply this mutation to the ASTRegistry
92    ///
93    /// # Arguments
94    ///
95    /// * `ctx` - Mutable context providing access to registries and event emission
96    ///
97    /// # Returns
98    ///
99    /// MutationResult indicating the number of changes made
100    fn apply_to_registry(&self, ctx: &mut ASTMutationContext) -> MutationResult;
101}