swc_ecma_minifier/pass/mangle_names/
mod.rs

1use std::{borrow::Cow, sync::Arc};
2
3use rustc_hash::FxHashSet;
4use swc_atoms::Atom;
5use swc_common::Mark;
6use swc_ecma_ast::*;
7use swc_ecma_transforms_base::rename::{renamer, RenameMap, Renamer};
8use swc_ecma_visit::VisitMutWith;
9
10pub(crate) use self::preserver::idents_to_preserve;
11use crate::{
12    option::{MangleCache, MangleOptions},
13    util::base54::Base54Chars,
14};
15
16mod mangler;
17mod preserver;
18
19pub(crate) fn mangle_names(
20    program: &mut Program,
21    options: &MangleOptions,
22    preserved: FxHashSet<Id>,
23    chars: Base54Chars,
24    top_level_mark: Mark,
25    mangle_name_cache: Option<Arc<dyn MangleCache>>,
26) {
27    let mut mangler = self::mangler::ManglerVisitor::new(options.keep_private_props, chars);
28    program.visit_mut_with(&mut mangler);
29
30    let mut cache = None;
31
32    if let Some(mangle_cache) = &mangle_name_cache {
33        let mut c = RenameMap::default();
34        mangle_cache.vars_cache(&mut |v| c.extend(v.iter().map(|(k, v)| (k.clone(), v.clone()))));
35        cache = Some(c);
36    }
37
38    program.visit_mut_with(&mut renamer(
39        swc_ecma_transforms_base::hygiene::Config {
40            keep_class_names: options.keep_class_names,
41            top_level_mark,
42            ignore_eval: options.eval,
43        },
44        ManglingRenamer {
45            chars,
46            preserved: &preserved,
47            cache,
48            mangle_name_cache,
49            reserved: &options.reserved,
50        },
51    ));
52}
53
54struct ManglingRenamer<'a> {
55    chars: Base54Chars,
56    preserved: &'a FxHashSet<Id>,
57    cache: Option<RenameMap>,
58    mangle_name_cache: Option<Arc<dyn MangleCache>>,
59    reserved: &'a Vec<Atom>,
60}
61
62impl<'a> Renamer for ManglingRenamer<'a> {
63    type Target = Atom;
64
65    const MANGLE: bool = true;
66    const RESET_N: bool = false;
67
68    fn new_name_for(&self, _: &Id, n: &mut usize) -> Atom {
69        self.chars.encode(n, true)
70    }
71
72    fn get_cached(&self) -> Option<Cow<RenameMap>> {
73        self.cache.as_ref().map(Cow::Borrowed)
74    }
75
76    fn store_cache(&mut self, update: &RenameMap) {
77        if let Some(cacher) = &self.mangle_name_cache {
78            cacher.update_vars_cache(update);
79        }
80    }
81
82    fn unresolved_symbols(&self) -> Vec<Atom> {
83        self.reserved
84            .iter()
85            .cloned()
86            .chain(self.preserved.iter().map(|id| id.0.clone()))
87            .collect()
88    }
89
90    fn preserve_name(&self, orig: &Id) -> bool {
91        self.preserved.contains(orig)
92    }
93}