swc_ecma_minifier/pass/mangle_names/
mod.rs1use 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}