swc_ecma_minifier/pass/mangle_names/
mangler.rs1use swc_ecma_ast::*;
2use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith};
3
4use self::{label_manger::LabelMangler, private_name_manger::PrivateNameMangler};
5use crate::util::base54::Base54Chars;
6
7mod label_manger {
8 use rustc_hash::FxHashMap;
9 use swc_atoms::Atom;
10 use swc_ecma_ast::*;
11
12 use crate::util::base54::Base54Chars;
13
14 pub(super) struct LabelMangler {
15 chars: Base54Chars,
16 cache: FxHashMap<Atom, Atom>,
17 n: usize,
18 }
19
20 impl LabelMangler {
21 pub(super) fn new(chars: Base54Chars) -> Self {
22 Self {
23 chars,
24 cache: FxHashMap::with_capacity_and_hasher(64, Default::default()),
25 n: Default::default(),
26 }
27 }
28
29 pub(super) fn mangle(&mut self, label: &mut Ident) {
30 if let Some(cached) = self.cache.get(&label.sym) {
32 label.sym = cached.clone();
33 return;
34 }
35
36 let new_sym = self.chars.encode(&mut self.n, true);
37 self.cache.insert(label.sym.clone(), new_sym.clone());
38 label.sym = new_sym;
39 }
40 }
41}
42
43mod private_name_manger {
44 use rustc_hash::FxHashMap;
45 use swc_atoms::Atom;
46 use swc_ecma_ast::*;
47
48 use crate::util::base54::Base54Chars;
49
50 pub(super) fn private_name_mangler(
51 keep_private_props: bool,
52 chars: Base54Chars,
53 ) -> PrivateNameMangler {
54 PrivateNameMangler {
55 keep_private_props,
56 private_n: Default::default(),
57 renamed_private: Default::default(),
58 chars,
59 }
60 }
61
62 pub(super) struct PrivateNameMangler {
63 chars: Base54Chars,
64 keep_private_props: bool,
65 private_n: usize,
66
67 renamed_private: FxHashMap<Atom, Atom>,
68 }
69
70 impl PrivateNameMangler {
71 pub(super) fn rename_private(&mut self, private_name: &mut PrivateName) {
72 if self.keep_private_props {
73 return;
74 }
75 let new_sym = if let Some(cached) = self.renamed_private.get(&private_name.name) {
76 cached.clone()
77 } else {
78 let sym = self.chars.encode(&mut self.private_n, true);
79
80 self.renamed_private
81 .insert(private_name.name.clone(), sym.clone());
82
83 sym
84 };
85
86 private_name.name = new_sym;
87 }
88 }
89}
90
91pub(super) struct ManglerVisitor {
92 label_mangler: LabelMangler,
93 private_name_mangler: PrivateNameMangler,
94}
95
96impl ManglerVisitor {
97 pub(super) fn new(keep_private_props: bool, chars: Base54Chars) -> Self {
98 Self {
99 label_mangler: LabelMangler::new(chars),
100 private_name_mangler: self::private_name_manger::private_name_mangler(
101 keep_private_props,
102 chars,
103 ),
104 }
105 }
106}
107
108impl VisitMut for ManglerVisitor {
109 noop_visit_mut_type!(fail);
110
111 fn visit_mut_private_name(&mut self, n: &mut PrivateName) {
112 self.private_name_mangler.rename_private(n);
113 }
114
115 fn visit_mut_labeled_stmt(&mut self, n: &mut LabeledStmt) {
116 self.label_mangler.mangle(&mut n.label);
117
118 n.visit_mut_children_with(self);
119 }
120
121 fn visit_mut_continue_stmt(&mut self, n: &mut ContinueStmt) {
122 if let Some(label) = &mut n.label {
123 self.label_mangler.mangle(label);
124 }
125
126 n.visit_mut_children_with(self);
127 }
128
129 fn visit_mut_break_stmt(&mut self, n: &mut BreakStmt) {
130 if let Some(label) = &mut n.label {
131 self.label_mangler.mangle(label);
132 }
133
134 n.visit_mut_children_with(self);
135 }
136}