use swc_atoms::Atom;
use swc_common::Mark;
use swc_ecma_ast::*;
use swc_ecma_utils::stack_size::maybe_grow_default;
use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith};
pub use crate::rename::rename;
use crate::rename::{renamer, Renamer};
#[cfg(test)]
mod tests;
#[derive(Debug, Clone, Default)]
pub struct Config {
pub keep_class_names: bool,
pub top_level_mark: Mark,
pub ignore_eval: bool,
}
impl Config {
pub fn hygiene_default() -> Self {
Self {
ignore_eval: true,
..Default::default()
}
}
}
pub fn hygiene() -> impl Pass + VisitMut {
hygiene_with_config(Config::hygiene_default())
}
pub fn hygiene_with_config(config: Config) -> impl 'static + Pass + VisitMut {
(
renamer(config, HygieneRenamer),
visit_mut_pass(HygieneRemover),
)
}
struct HygieneRenamer;
impl Renamer for HygieneRenamer {
type Target = Atom;
const MANGLE: bool = false;
const RESET_N: bool = true;
fn new_name_for(&self, orig: &Id, n: &mut usize) -> swc_atoms::Atom {
let res = if *n == 0 {
orig.0.clone()
} else {
format!("{}{}", orig.0, n).into()
};
*n += 1;
res
}
}
struct HygieneRemover;
impl VisitMut for HygieneRemover {
noop_visit_mut_type!();
fn visit_mut_expr(&mut self, n: &mut Expr) {
maybe_grow_default(|| n.visit_mut_children_with(self));
}
fn visit_mut_ident(&mut self, i: &mut Ident) {
i.ctxt = Default::default();
}
}