ricecoder_lsp/
refactoring.rs1use ricecoder_refactoring::{
7 ConfigManager, GenericRefactoringProvider, ImpactAnalyzer, ProviderRegistry, RefactoringEngine, RefactoringType,
8};
9use serde_json::Value;
10use std::sync::Arc;
11use tracing::{debug, info};
12
13pub struct RefactoringHandler {
15 engine: Arc<RefactoringEngine>,
17 impact_analyzer: Arc<ImpactAnalyzer>,
19 config_manager: Arc<ConfigManager>,
21 enabled: bool,
23}
24
25impl RefactoringHandler {
26 pub fn new() -> Self {
28 let config_manager = ConfigManager::new();
29
30 let generic_provider = Arc::new(GenericRefactoringProvider::new());
32
33 let provider_registry = ProviderRegistry::new(generic_provider);
35
36 let engine = Arc::new(RefactoringEngine::new(config_manager, provider_registry));
37 let impact_analyzer = Arc::new(ImpactAnalyzer::new());
38
39 let config_manager = Arc::new(ConfigManager::new());
41
42 Self {
43 engine,
44 impact_analyzer,
45 config_manager,
46 enabled: true,
47 }
48 }
49
50 pub fn set_enabled(&mut self, enabled: bool) {
52 self.enabled = enabled;
53 if enabled {
54 info!("Refactoring engine enabled");
55 } else {
56 info!("Refactoring engine disabled");
57 }
58 }
59
60 pub fn is_enabled(&self) -> bool {
62 self.enabled
63 }
64
65 pub fn engine(&self) -> Arc<RefactoringEngine> {
67 self.engine.clone()
68 }
69
70 pub fn impact_analyzer(&self) -> Arc<ImpactAnalyzer> {
72 self.impact_analyzer.clone()
73 }
74
75
76
77 pub fn config_manager(&self) -> Arc<ConfigManager> {
79 self.config_manager.clone()
80 }
81
82 pub async fn handle_refactoring_request(
84 &self,
85 params: Value,
86 ) -> Result<Value, String> {
87 if !self.enabled {
88 return Err("Refactoring engine is disabled".to_string());
89 }
90
91 debug!("Handling refactoring request: {:?}", params);
92
93 let refactoring_type = params
95 .get("refactoringType")
96 .and_then(|v| v.as_str())
97 .ok_or("Missing refactoringType")?;
98
99 let file_uri = params
101 .get("fileUri")
102 .and_then(|v| v.as_str())
103 .ok_or("Missing fileUri")?;
104
105 let symbol = params
107 .get("symbol")
108 .and_then(|v| v.as_str())
109 .ok_or("Missing symbol")?;
110
111 info!(
112 "Processing refactoring: type={}, file={}, symbol={}",
113 refactoring_type, file_uri, symbol
114 );
115
116 Ok(serde_json::json!({
117 "success": true,
118 "message": format!("Refactoring {} for {} in {} queued", refactoring_type, symbol, file_uri)
119 }))
120 }
121
122 pub fn available_refactoring_types(&self) -> Vec<&'static str> {
124 vec![
125 "Rename",
126 "Extract",
127 "Inline",
128 "Move",
129 "ChangeSignature",
130 "RemoveUnused",
131 "Simplify",
132 ]
133 }
134
135 pub async fn get_language_config(&self, language: &str) -> Result<Value, String> {
137 debug!("Getting refactoring configuration for language: {}", language);
138
139 let provider = self.engine.provider_registry().clone().get_provider(language);
141
142 let analysis = provider.analyze_refactoring("code", language, RefactoringType::Rename);
144
145 if analysis.is_ok() {
146 info!("Refactoring provider available for {}", language);
147 Ok(serde_json::json!({
148 "language": language,
149 "available": true
150 }))
151 } else {
152 info!("No refactoring provider for {}", language);
153 Err(format!("No refactoring provider for {}", language))
154 }
155 }
156}
157
158impl Default for RefactoringHandler {
159 fn default() -> Self {
160 Self::new()
161 }
162}
163
164#[cfg(test)]
165mod tests {
166 use super::*;
167
168 #[test]
169 fn test_refactoring_handler_creation() {
170 let handler = RefactoringHandler::new();
171 assert!(handler.is_enabled());
172 }
173
174 #[test]
175 fn test_refactoring_handler_enable_disable() {
176 let mut handler = RefactoringHandler::new();
177 assert!(handler.is_enabled());
178
179 handler.set_enabled(false);
180 assert!(!handler.is_enabled());
181
182 handler.set_enabled(true);
183 assert!(handler.is_enabled());
184 }
185
186 #[test]
187 fn test_available_refactoring_types() {
188 let handler = RefactoringHandler::new();
189 let types = handler.available_refactoring_types();
190 assert!(!types.is_empty());
191 assert!(types.contains(&"Rename"));
192 assert!(types.contains(&"Extract"));
193 }
194}