1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
use swc_core::plugin::{plugin_transform, proxies::TransformPluginProgramMetadata};
use swc_core::{
common::util::take::Take,
ecma::{
ast::*,
visit::{as_folder, FoldWith, VisitMut, VisitMutWith},
},
};
pub struct TransformVisitor;
impl VisitMut for TransformVisitor {
// Implement necessary visit_mut_* methods for actual custom transform.
// A comprehensive list of possible visitor methods can be found here:
// https://rustdoc.swc.rs/swc_ecma_visit/trait.VisitMut.html
fn visit_mut_stmt(&mut self, n: &mut Stmt) {
n.visit_mut_children_with(self);
match n {
Stmt::Expr(exprStmt) => match &*exprStmt.expr {
Expr::Call(call) => match &call.callee {
Callee::Expr(callee_expr) => match &**callee_expr {
Expr::Member(member) => {
if let Expr::Ident(ident) = &*member.obj {
if ident.sym.eq("console".into()) {
n.take();
}
}
}
_ => {}
},
_ => {}
},
_ => {}
},
_ => {}
}
}
fn visit_mut_stmts(&mut self, stmts: &mut Vec<Stmt>) {
stmts.visit_mut_children_with(self);
// We do same thing here.
stmts.retain(|s| !matches!(s, Stmt::Empty(..)));
}
}
/// An example plugin function with macro support.
/// `plugin_transform` macro interop pointers into deserialized structs, as well
/// as returning ptr back to host.
///
/// It is possible to opt out from macro by writing transform fn manually
/// if plugin need to handle low-level ptr directly via
/// `__transform_plugin_process_impl(
/// ast_ptr: *const u8, ast_ptr_len: i32,
/// unresolved_mark: u32, should_enable_comments_proxy: i32) ->
/// i32 /* 0 for success, fail otherwise.
/// Note this is only for internal pointer interop result,
/// not actual transform result */`
///
/// This requires manual handling of serialization / deserialization from ptrs.
/// Refer swc_plugin_macro to see how does it work internally.
#[plugin_transform]
pub fn process_transform(program: Program, _metadata: TransformPluginProgramMetadata) -> Program {
program.fold_with(&mut as_folder(TransformVisitor))
}
// An example to test plugin transform.
// Recommended strategy to test plugin's transform is verify
// the Visitor's behavior, instead of trying to run `process_transform` with mocks
// unless explicitly required to do so.
// test!(
// Default::default(),
// |_| as_folder(TransformVisitor),
// boo,
// // Input codes
// r#"foo === bar;"#,
// // Output codes after transformed with plugin
// r#"kdy1 === bar;"#
// );