use syntax::ast::Crate;
use crate::command::{Command, CommandState, RefactorState, Registry};
use crate::driver::Phase;
use crate::RefactorCtxt;
pub trait Transform {
fn transform(&self, krate: &mut Crate, st: &CommandState, cx: &RefactorCtxt);
fn min_phase(&self) -> Phase {
Phase::Phase2
}
}
pub struct TransformCommand<T: Transform>(pub T);
impl<T: Transform> Command for TransformCommand<T> {
fn run(&mut self, state: &mut RefactorState) {
state
.transform_crate(self.0.min_phase(), |st, cx| {
self.0.transform(&mut *st.krate_mut(), st, cx)
})
.expect("Failed to run compiler");
}
}
fn mk<T: Transform + 'static>(t: T) -> Box<dyn Command> {
Box::new(TransformCommand(t))
}
macro_rules! transform_modules {
($($name:ident,)*) => {
$( pub mod $name; )*
pub fn register_commands(reg: &mut Registry) {
$( $name::register_commands(reg); )*
}
};
}
transform_modules! {
canonicalize_refs,
casts,
char_literals,
control_flow,
externs,
format,
funcs,
generics,
ionize,
items,
linkage,
literals,
reorganize_definitions,
ownership,
retype,
rewrite,
statics,
structs,
test,
vars,
}