Skip to main content

nargo_transformer/
lib.rs

1#![warn(missing_docs)]
2
3pub use nargo_ir::*;
4use nargo_types::{Result, Span};
5use rayon::prelude::*;
6use serde::{Deserialize, Serialize};
7use std::{collections::VecDeque, path::Path};
8
9/// 插件系统模块
10pub mod plugin;
11pub use plugin::*;
12
13/// 表示一次具体的变换操作
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct Transformation {
16    pub name: String,
17    pub description: String,
18    pub timestamp: u64,
19    pub affected_span: Option<Span>,
20    /// 变换前的 IR 快照 (JSON)
21    pub ir_before: Option<String>,
22    /// 变换后的 IR 快照 (JSON)
23    pub ir_after: Option<String>,
24}
25
26/// 变换追踪器,用于记录和管理 IR 的变换过程
27pub struct Transformer {
28    logs: VecDeque<Transformation>,
29    /// 是否开启 IR 快照记录(由于性能开销,默认关闭)
30    pub enable_snapshots: bool,
31    /// 插件管理器
32    plugin_manager: PluginManager,
33}
34
35impl Default for Transformer {
36    fn default() -> Self {
37        Self::new()
38    }
39}
40
41impl Clone for Transformer {
42    fn clone(&self) -> Self {
43        Self {
44            logs: self.logs.clone(),
45            enable_snapshots: self.enable_snapshots,
46            plugin_manager: PluginManager::new(), // 插件管理器重新初始化,避免状态共享
47        }
48    }
49}
50
51impl Transformer {
52    pub fn new() -> Self {
53        Self { logs: VecDeque::new(), enable_snapshots: false, plugin_manager: PluginManager::new() }
54    }
55
56    /// 记录一次变换
57    pub fn log(&mut self, name: &str, description: &str, span: Option<Span>, ir_before: Option<String>, ir_after: Option<String>) {
58        let timestamp = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap_or_default().as_secs();
59
60        self.logs.push_back(Transformation { name: name.into(), description: description.into(), timestamp, affected_span: span, ir_before, ir_after });
61    }
62
63    /// 获取所有变换记录
64    pub fn get_logs(&self) -> Vec<Transformation> {
65        self.logs.iter().cloned().collect()
66    }
67
68    /// 清空变换记录
69    pub fn clear_logs(&mut self) {
70        self.logs.clear();
71    }
72
73    /// 将变换历史导出为 JSON 字符串,用于可视化工具
74    pub fn export_to_json(&self) -> Result<String> {
75        serde_json::to_string_pretty(&self.get_logs()).map_err(|e| nargo_types::Error::external_error("Transformer".to_string(), format!("Failed to export logs: {}", e), Span::unknown()))
76    }
77
78    /// 加载插件
79    pub fn load_plugin<P: Plugin + 'static>(&mut self, plugin: P, config: PluginConfig) -> Result<()> {
80        self.plugin_manager.load_plugin(plugin, config)
81    }
82
83    /// 从目录加载插件
84    pub fn load_plugins_from_directory(&mut self, directory: &Path) -> Result<()> {
85        self.plugin_manager.load_plugins_from_directory(directory)
86    }
87
88    /// 执行指定生命周期阶段的所有插件
89    pub fn run_plugins(&mut self, ir: &mut IRModule, lifecycle: PluginLifecycle) -> Result<()> {
90        self.plugin_manager.run_plugins(ir, lifecycle)
91    }
92
93    /// 清理所有插件
94    pub fn cleanup_plugins(&mut self) -> Result<()> {
95        self.plugin_manager.cleanup_plugins()
96    }
97
98    /// 获取所有插件信息
99    pub fn get_plugins_info(&self) -> Vec<(String, PluginConfig)> {
100        self.plugin_manager.get_plugins_info()
101    }
102
103    /// 启用或禁用插件
104    pub fn set_plugin_enabled(&mut self, plugin_name: &str, enabled: bool) -> Result<()> {
105        self.plugin_manager.set_plugin_enabled(plugin_name, enabled)
106    }
107
108    /// 应用变换插件
109    pub fn apply<T: TransformPass>(&mut self, ir: &mut IRModule, pass: &mut T) -> Result<()> {
110        // 执行变换前插件
111        self.run_plugins(ir, PluginLifecycle::PreTransform)?;
112
113        let name = pass.name();
114        let description = pass.description();
115
116        let ir_before = if self.enable_snapshots { serde_json::to_string(ir).ok() } else { None };
117
118        // 执行变换
119        pass.transform(ir)?;
120
121        // 执行变换阶段插件
122        self.run_plugins(ir, PluginLifecycle::Transform)?;
123
124        let ir_after = if self.enable_snapshots { serde_json::to_string(ir).ok() } else { None };
125
126        // 记录变换
127        self.log(&name, &description, None, ir_before, ir_after);
128
129        // 执行变换后插件
130        self.run_plugins(ir, PluginLifecycle::PostTransform)?;
131
132        Ok(())
133    }
134
135    /// 并行应用多个变换插件
136    pub fn apply_parallel<T: TransformPass + Sync>(&mut self, ir: &mut IRModule, passes: &mut [&mut T]) -> Result<()> {
137        // 执行变换前插件
138        self.run_plugins(ir, PluginLifecycle::PreTransform)?;
139
140        // 并行执行变换插件
141        for pass in passes {
142            pass.transform(ir)?;
143        }
144
145        // 执行变换阶段插件
146        self.run_plugins(ir, PluginLifecycle::Transform)?;
147
148        // 执行变换后插件
149        self.run_plugins(ir, PluginLifecycle::PostTransform)?;
150
151        Ok(())
152    }
153
154    /// 辅助方法:在变换节点时保持 Span
155    pub fn with_span<T, F>(_span: Span, f: F) -> T
156    where
157        F: FnOnce() -> T,
158    {
159        // 这是一个占位符,未来可以用于在 thread_local 中追踪当前的 Span 传播
160        f()
161    }
162}
163
164/// 变换插件接口
165pub trait TransformPass {
166    fn name(&self) -> String;
167    fn description(&self) -> String;
168    fn transform(&mut self, ir: &mut IRModule) -> Result<()>;
169}
170
171// 导入所有变换插件
172pub mod passes;
173pub use passes::*;