# HXO Transformer 插件开发文档
## 概述
HXO Transformer 插件系统允许开发者扩展和定制 HXO 的代码变换过程。通过插件,您可以:
- 在变换过程的不同阶段执行自定义逻辑
- 修改 IR(中间表示)以实现特定功能
- 集成第三方工具和服务
- 自定义代码分析和优化
## 插件接口
所有 HXO Transformer 插件都必须实现 `Plugin` trait,该 trait 定义了以下方法:
```rust
pub trait Plugin: Send + Sync {
/// 获取插件名称
fn name(&self) -> String;
/// 获取插件描述
fn description(&self) -> String;
/// 初始化插件
fn init(&mut self, config: &PluginConfig) -> Result<()>;
/// 执行插件逻辑
fn run(&mut self, ir: &mut IRModule, lifecycle: PluginLifecycle) -> Result<()>;
/// 清理插件资源
fn cleanup(&mut self) -> Result<()>;
}
```
## 插件生命周期
HXO Transformer 插件系统定义了以下生命周期阶段:
1. **Init**:插件首次加载时执行,用于初始化插件资源和配置
2. **PreTransform**:在所有变换开始前执行,可用于准备变换环境
3. **Transform**:与内置变换一起执行,可用于修改 IR
4. **PostTransform**:在所有变换完成后执行,可用于最终处理
5. **Cleanup**:在整个变换过程结束后执行,用于清理插件资源
## 插件配置
插件配置通过 `PluginConfig` 结构体定义,包含以下字段:
```rust
pub struct PluginConfig {
/// 插件名称
pub name: String,
/// 插件版本
pub version: String,
/// 插件描述
pub description: String,
/// 插件优先级(数值越小,优先级越高)
pub priority: i32,
/// 插件配置参数
pub config: HashMap<String, NargoValue>,
/// 插件启用状态
pub enabled: bool,
}
```
## 开发插件
### 步骤 1:创建插件结构体
首先,创建一个实现 `Plugin` trait 的结构体:
```rust
use nargo_types::{Result, Span};
use nargo_transformer::{Plugin, PluginConfig, PluginLifecycle, IRModule};
pub struct MyPlugin {
// 插件内部状态
config: Option<PluginConfig>,
}
impl MyPlugin {
pub fn new() -> Self {
Self {
config: None,
}
}
}
```
### 步骤 2:实现 Plugin trait
为您的插件实现 `Plugin` trait 的所有方法:
```rust
impl Plugin for MyPlugin {
fn name(&self) -> String {
"my-plugin".to_string()
}
fn description(&self) -> String {
"我的自定义插件".to_string()
}
fn init(&mut self, config: &PluginConfig) -> Result<()> {
self.config = Some(config.clone());
// 初始化逻辑
Ok(())
}
fn run(&mut self, ir: &mut IRModule, lifecycle: PluginLifecycle) -> Result<()> {
// 根据生命周期阶段执行不同的逻辑
match lifecycle {
PluginLifecycle::Init => {
// 初始化阶段逻辑
}
PluginLifecycle::PreTransform => {
// 变换前阶段逻辑
}
PluginLifecycle::Transform => {
// 变换阶段逻辑
}
PluginLifecycle::PostTransform => {
// 变换后阶段逻辑
}
PluginLifecycle::Cleanup => {
// 清理阶段逻辑
}
}
Ok(())
}
fn cleanup(&mut self) -> Result<()> {
// 清理逻辑
Ok(())
}
}
```
### 步骤 3:注册插件
在您的代码中,使用 `Transformer` 的 `load_plugin` 方法加载插件:
```rust
use nargo_transformer::{Transformer, PluginConfig};
use my_plugin::MyPlugin;
let mut transformer = Transformer::new();
// 创建插件配置
let plugin_config = PluginConfig {
name: "my-plugin".to_string(),
version: "1.0.0".to_string(),
description: "我的自定义插件".to_string(),
priority: 0,
config: Default::default(),
enabled: true,
};
// 加载插件
transformer.load_plugin(MyPlugin::new(), plugin_config).unwrap();
```
## 示例插件
以下是一个完整的示例插件,用于在变换过程中添加日志:
```rust
use nargo_types::{Result, Span};
use nargo_transformer::{Plugin, PluginConfig, PluginLifecycle, IRModule};
/// 日志插件,用于在变换过程中添加日志
pub struct LogPlugin {
config: Option<PluginConfig>,
}
impl LogPlugin {
pub fn new() -> Self {
Self {
config: None,
}
}
}
impl Plugin for LogPlugin {
fn name(&self) -> String {
"log-plugin".to_string()
}
fn description(&self) -> String {
"在变换过程中添加日志".to_string()
}
fn init(&mut self, config: &PluginConfig) -> Result<()> {
self.config = Some(config.clone());
println!("LogPlugin initialized");
Ok(())
}
fn run(&mut self, ir: &mut IRModule, lifecycle: PluginLifecycle) -> Result<()> {
println!("LogPlugin running at lifecycle: {:?}", lifecycle);
// 可以在这里添加更详细的日志,例如 IR 的结构信息
Ok(())
}
fn cleanup(&mut self) -> Result<()> {
println!("LogPlugin cleaned up");
Ok(())
}
}
```
## 插件优先级
插件的执行顺序由其优先级决定,优先级数值越小,执行顺序越早。您可以在 `PluginConfig` 中设置插件的优先级:
```rust
let plugin_config = PluginConfig {
// 其他配置...
priority: -10, // 高优先级
// 其他配置...
};
```
## 插件配置参数
您可以在 `PluginConfig` 的 `config` 字段中设置插件的配置参数,这些参数会在插件初始化时传递给插件:
```rust
use nargo_types::NargoValue;
use std::collections::HashMap;
let mut config_map = HashMap::new();
config_map.insert("debug".to_string(), NargoValue::Boolean(true));
config_map.insert("max_depth".to_string(), NargoValue::Number(10.0));
let plugin_config = PluginConfig {
// 其他配置...
config: config_map,
// 其他配置...
};
```
## 插件加载
除了通过代码加载插件外,您还可以通过目录加载插件:
```rust
use std::path::Path;
let plugin_dir = Path::new("./plugins");
transformer.load_plugins_from_directory(plugin_dir).unwrap();
```
## 插件管理
`Transformer` 提供了以下方法来管理插件:
- `load_plugin`:加载单个插件
- `load_plugins_from_directory`:从目录加载插件
- `run_plugins`:执行指定生命周期阶段的所有插件
- `cleanup_plugins`:清理所有插件
- `get_plugins_info`:获取所有插件信息
- `set_plugin_enabled`:启用或禁用插件
## 注意事项
1. 插件应该是无状态的,或者在 `cleanup` 方法中清理所有状态
2. 插件应该处理好错误,确保不会导致整个变换过程失败
3. 插件应该遵循 HXO 的代码风格和最佳实践
4. 插件应该有清晰的文档和注释
## 测试插件
您可以使用 HXO 的测试框架来测试您的插件:
```rust
use nargo_transformer::{Transformer, PluginConfig};
use my_plugin::MyPlugin;
#[test]
fn test_my_plugin() {
let mut transformer = Transformer::new();
let plugin_config = PluginConfig {
name: "my-plugin".to_string(),
version: "1.0.0".to_string(),
description: "我的自定义插件".to_string(),
priority: 0,
config: Default::default(),
enabled: true,
};
transformer.load_plugin(MyPlugin::new(), plugin_config).unwrap();
// 创建测试 IR
let mut ir = IRModule::default();
// 执行变换
transformer.run_plugins(&mut ir, PluginLifecycle::PreTransform).unwrap();
transformer.run_plugins(&mut ir, PluginLifecycle::Transform).unwrap();
transformer.run_plugins(&mut ir, PluginLifecycle::PostTransform).unwrap();
// 清理插件
transformer.cleanup_plugins().unwrap();
}
```
## 结论
HXO Transformer 插件系统为开发者提供了一种灵活的方式来扩展和定制 HXO 的代码变换过程。通过实现 `Plugin` trait,您可以在变换过程的不同阶段执行自定义逻辑,从而实现各种功能和优化。
希望本文档对您开发 HXO Transformer 插件有所帮助!