gpt4 book ai didi

rust - 使用VisitMut时如何插入Expr?

转载 作者:行者123 更新时间:2023-12-03 11:36:20 27 4
gpt4 key购买 nike

我目前正在使用syn以下示例创建可突变的AST。我了解我可以修改正在移动的节点(如下所示,在当前代码中显示),但是
我很好奇我是否可以在当前节点和下一个节点之间添加一些代码。联合整理箱有能力做到这一点吗?

use syn::visit_mut::{self, VisitMut};
use syn::Expr;

#[derive(Debug)]
struct MyStruct;

impl VisitMut for MyStruct {
fn visit_expr_mut(&mut self, node: &mut Expr) {
if let Expr::MethodCall(expr) = &node.to_owned() {
// I can modify the existing node like so:
*node = parse_quote!("// Hello World");

// How could I add something after this node and before the next?
}
}
}

pub fn create() {
let current_dir = std::env::current_dir().expect("Unable to get current directory");
let rust_file = std::fs::read_to_string(current_dir.join("src").join("lib.rs")).expect("Unable to read rust file");
let ast = syn::parse_file(&rust_file).expect("Unable to create AST from rust file");

MyStruct.visit_file_mut(&mut ast);
}
编辑以显示用例:
我当前正在解析的文件如下所示:
#[macro_use]
extern crate foo;
mod test;
fn init(handle: foo::InitHandle) {
handle.add_class::<Test::test>();
}
假设当我阅读AST时,我想为其添加另一个mod和另一个句柄,如下所示:
#[macro_use]
extern crate foo;
mod test;
mod store;
fn init(handle: foo::InitHandle) {
handle.add_class::<Test::test>();
handle.add_class::<Store::store>();
}

最佳答案

正如我所评论的,这在很大程度上取决于您要插入的内容。因为您不能只在node之前或之后轻松插入任何内容。
对于您的特定情况,可以使用 parse_quote! 生成 ExprBlock

*node = parse_quote!(
{
#expr;
handle.add_class::<Store::store>();
}
);
其中具有以下输入:
fn init(handle: foo::InitHandle) {
handle.add_class::<Test::test>();
}
将产生以下输出:
fn init(handle: foo::InitHandle) {
{
handle.add_class::<Test::test>();
handle.add_class::<Store::store>();
};
}
(请注意,我已经重新格式化了输出,以便更漂亮)

或者,您可以改写 visit_block_mut() 。这样,您就可以访问 stmts: Vec<Stmt> ,并且可以在 Stmt 之前和之后插入。 的缺点是,通过这种方式,您将无法像使用 Expr s那样轻松访问所有 visit_expr_mut()

关于rust - 使用VisitMut时如何插入Expr?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65765082/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com