Skip to main content

ryo_executor/executor/registry/converters/
rename.rs

1//! RenameConverter: Converts MutationSpec::Rename to RenameMutation
2
3use crate::engine::ASTRegApply;
4use crate::executor::registry::converters::ResolveTargetSymbol;
5use crate::executor::registry::{ConvertError, MutationConverter};
6use crate::executor::spec::MutationSpec;
7use ryo_analysis::AnalysisContext;
8use ryo_mutations::RenameMutation;
9
10/// Converter for Rename mutations
11#[derive(Debug, Clone, Default)]
12pub struct RenameConverter;
13
14impl RenameConverter {
15    pub fn new() -> Self {
16        Self
17    }
18}
19
20// RenameConverter uses the default implementation of ResolveTargetSymbol
21impl ResolveTargetSymbol for RenameConverter {}
22
23impl MutationConverter for RenameConverter {
24    fn spec_kinds(&self) -> &'static [&'static str] {
25        &["Rename"]
26    }
27
28    fn convert_v2(
29        &self,
30        spec: &MutationSpec,
31        ctx: &AnalysisContext,
32    ) -> Result<Vec<Box<dyn ASTRegApply>>, ConvertError> {
33        match spec {
34            MutationSpec::Rename {
35                target: target_symbol,
36                to,
37                ..
38            } => {
39                // Resolve target_symbol to SymbolId
40                let symbol_id = self.resolve_target_symbol(target_symbol, ctx)?;
41                let mutation = RenameMutation::new(symbol_id, to);
42                Ok(vec![Box::new(mutation)])
43            }
44            _ => Err(ConvertError::TypeMismatch {
45                expected: "Rename",
46                actual: spec.kind_name().to_string(),
47            }),
48        }
49    }
50}
51
52#[cfg(test)]
53mod tests {
54    use super::*;
55    use crate::executor::spec::Scope;
56    use ryo_symbol::{SymbolKind, SymbolPath, SymbolRegistry};
57
58    #[test]
59    fn test_rename_converter_spec_kinds() {
60        let converter = RenameConverter::new();
61        assert_eq!(converter.spec_kinds(), &["Rename"]);
62    }
63
64    #[test]
65    fn test_rename_converter_can_handle() {
66        let converter = RenameConverter::new();
67
68        let mut registry = SymbolRegistry::new();
69        let path = SymbolPath::parse("test_crate::old").unwrap();
70        let symbol_id = registry.register(path, SymbolKind::Function).unwrap();
71
72        let rename_spec = MutationSpec::Rename {
73            target: crate::executor::spec::MutationTargetSymbol::ById(symbol_id),
74            to: "new".into(),
75            scope: Scope::Project,
76        };
77        assert!(converter.can_handle(&rename_spec));
78
79        let add_field_spec = MutationSpec::AddField {
80            target: crate::executor::spec::MutationTargetSymbol::ById(symbol_id),
81            field_name: "bar".into(),
82            field_type: "i32".into(),
83            visibility: crate::executor::spec::Visibility::Private,
84        };
85        assert!(!converter.can_handle(&add_field_spec));
86    }
87}