use syntax::ast::Crate;
use syntax::symbol::Symbol;
use crate::command::{CommandState, Registry};
use crate::contains_mark::contains_mark;
use crate::driver::Phase;
use crate::matcher::{MatchCtxt, Subst, mut_visit_match_with};
use crate::transform::Transform;
use c2rust_ast_builder::IntoSymbol;
use crate::RefactorCtxt;
pub struct RewriteExpr {
pub pat: String,
pub repl: String,
pub filter: Option<Symbol>,
}
impl Transform for RewriteExpr {
fn transform(&self, krate: &mut Crate, st: &CommandState, cx: &RefactorCtxt) {
let mut mcx = MatchCtxt::new(st, cx);
let pat = mcx.parse_expr(&self.pat);
let repl = mcx.parse_expr(&self.repl);
mut_visit_match_with(mcx, pat, krate, |ast, mcx| {
if let Some(filter) = self.filter {
if !contains_mark(&**ast, filter, st) {
return;
}
}
*ast = repl.clone().subst(st, cx, &mcx.bindings);
})
}
fn min_phase(&self) -> Phase {
Phase::Phase3
}
}
pub struct RewriteTy {
pub pat: String,
pub repl: String,
pub filter: Option<Symbol>,
}
impl Transform for RewriteTy {
fn transform(&self, krate: &mut Crate, st: &CommandState, cx: &RefactorCtxt) {
let mut mcx = MatchCtxt::new(st, cx);
let pat = mcx.parse_ty(&self.pat);
let repl = mcx.parse_ty(&self.repl);
mut_visit_match_with(mcx, pat, krate, |ast, mcx| {
if let Some(filter) = self.filter {
if !contains_mark(&**ast, filter, st) {
return;
}
}
*ast = repl.clone().subst(st, cx, &mcx.bindings);
})
}
fn min_phase(&self) -> Phase {
Phase::Phase3
}
}
pub struct RewriteStmts {
pub pat: String,
pub repl: String,
}
impl Transform for RewriteStmts {
fn transform(&self, krate: &mut Crate, st: &CommandState, cx: &RefactorCtxt) {
let mut mcx = MatchCtxt::new(st, cx);
let pat = mcx.parse_stmts(&self.pat);
let repl = mcx.parse_stmts(&self.repl);
mut_visit_match_with(mcx, pat, krate, |ast, mcx| {
*ast = repl.clone().subst(st, cx, &mcx.bindings);
})
}
fn min_phase(&self) -> Phase {
Phase::Phase3
}
}
pub struct DebugMatchExpr {
pub pat: String,
}
impl Transform for DebugMatchExpr {
fn transform(&self, krate: &mut Crate, st: &CommandState, cx: &RefactorCtxt) {
let mut init_mcx = MatchCtxt::new(st, cx);
init_mcx.debug = true;
let pat = init_mcx.parse_expr(&self.pat);
mut_visit_match_with(init_mcx, pat, krate, |ast, _mcx| {
eprintln!("matched node {:?}", ast);
})
}
fn min_phase(&self) -> Phase {
Phase::Phase3
}
}
pub fn register_commands(reg: &mut Registry) {
use super::mk;
reg.register("rewrite_expr", |args| mk(RewriteExpr {
pat: args[0].clone(),
repl: args[1].clone(),
filter: if args.len() >= 3 { Some((&args[2]).into_symbol()) } else { None },
}));
reg.register("rewrite_ty", |args| mk(RewriteTy {
pat: args[0].clone(),
repl: args[1].clone(),
filter: if args.len() >= 3 { Some((&args[2]).into_symbol()) } else { None },
}));
reg.register("rewrite_stmts", |args| mk(RewriteStmts {
pat: args[0].clone(),
repl: args[1].clone(),
}));
reg.register("debug_match_expr", |args| mk(DebugMatchExpr {
pat: args[0].clone(),
}));
}