|
1 |
| -use std::sync::Arc; |
2 |
| - |
3 |
| -use compat::es2015::regenerator; |
4 |
| -use either::Either; |
5 |
| -use rustc_hash::FxHashMap; |
6 |
| -use swc_atoms::Atom; |
7 |
| -use swc_common::{ |
8 |
| - comments::Comments, errors::Handler, sync::Lrc, util::take::Take, FileName, Mark, SourceMap, |
9 |
| -}; |
10 |
| -use swc_ecma_ast::{EsVersion, Module, Pass, Script}; |
| 1 | +use swc_common::{comments::Comments, sync::Lrc, util::take::Take, Mark, SourceMap}; |
| 2 | +use swc_ecma_ast::{Module, Script}; |
11 | 3 | use swc_ecma_minifier::option::{terser::TerserTopLevelOptions, MinifyOptions};
|
12 |
| -use swc_ecma_parser::Syntax; |
13 |
| -use swc_ecma_preset_env::Caniuse; |
14 |
| -use swc_ecma_transforms::{ |
15 |
| - compat, |
16 |
| - fixer::{fixer, paren_remover}, |
17 |
| - helpers, |
18 |
| - hygiene::{self, hygiene_with_config}, |
19 |
| - modules::{self, path::ImportResolver}, |
20 |
| - optimization::const_modules, |
21 |
| - resolver, Assumptions, |
22 |
| -}; |
23 |
| -use swc_ecma_visit::{noop_visit_mut_type, visit_mut_pass, VisitMut, VisitMutWith}; |
24 |
| -use swc_visit::Optional; |
25 |
| - |
26 |
| -use crate::config::{GlobalPassOption, JsMinifyOptions, ModuleConfig}; |
27 |
| - |
28 |
| -/// Builder is used to create a high performance `Compiler`. |
29 |
| -pub struct PassBuilder<'a, 'b, P: Pass> { |
30 |
| - cm: &'a Arc<SourceMap>, |
31 |
| - handler: &'b Handler, |
32 |
| - env: Option<swc_ecma_preset_env::EnvConfig>, |
33 |
| - pass: P, |
34 |
| - /// [Mark] for top level bindings . |
35 |
| - top_level_mark: Mark, |
36 |
| - |
37 |
| - /// [Mark] for unresolved refernces. |
38 |
| - unresolved_mark: Mark, |
39 |
| - |
40 |
| - target: EsVersion, |
41 |
| - loose: bool, |
42 |
| - assumptions: Assumptions, |
43 |
| - hygiene: Option<hygiene::Config>, |
44 |
| - fixer: bool, |
45 |
| - inject_helpers: bool, |
46 |
| - minify: Option<JsMinifyOptions>, |
47 |
| - regenerator: regenerator::Config, |
48 |
| -} |
| 4 | +use swc_ecma_transforms::{hygiene::hygiene_with_config, resolver}; |
| 5 | +use swc_ecma_visit::{noop_visit_mut_type, VisitMut, VisitMutWith}; |
49 | 6 |
|
50 |
| -impl<'a, 'b, P: Pass> PassBuilder<'a, 'b, P> { |
51 |
| - pub fn new( |
52 |
| - cm: &'a Arc<SourceMap>, |
53 |
| - handler: &'b Handler, |
54 |
| - loose: bool, |
55 |
| - assumptions: Assumptions, |
56 |
| - top_level_mark: Mark, |
57 |
| - unresolved_mark: Mark, |
58 |
| - pass: P, |
59 |
| - ) -> Self { |
60 |
| - PassBuilder { |
61 |
| - cm, |
62 |
| - handler, |
63 |
| - env: None, |
64 |
| - pass, |
65 |
| - top_level_mark, |
66 |
| - unresolved_mark, |
67 |
| - target: EsVersion::Es5, |
68 |
| - loose, |
69 |
| - assumptions, |
70 |
| - hygiene: Some(Default::default()), |
71 |
| - fixer: true, |
72 |
| - inject_helpers: true, |
73 |
| - minify: None, |
74 |
| - regenerator: Default::default(), |
75 |
| - } |
76 |
| - } |
77 |
| - |
78 |
| - pub fn then<N>(self, next: N) -> PassBuilder<'a, 'b, (P, N)> |
79 |
| - where |
80 |
| - N: Pass, |
81 |
| - { |
82 |
| - let pass = (self.pass, next); |
83 |
| - PassBuilder { |
84 |
| - cm: self.cm, |
85 |
| - handler: self.handler, |
86 |
| - env: self.env, |
87 |
| - pass, |
88 |
| - top_level_mark: self.top_level_mark, |
89 |
| - unresolved_mark: self.unresolved_mark, |
90 |
| - target: self.target, |
91 |
| - loose: self.loose, |
92 |
| - assumptions: self.assumptions, |
93 |
| - hygiene: self.hygiene, |
94 |
| - fixer: self.fixer, |
95 |
| - inject_helpers: self.inject_helpers, |
96 |
| - minify: self.minify, |
97 |
| - regenerator: self.regenerator, |
98 |
| - } |
99 |
| - } |
100 |
| - |
101 |
| - pub fn skip_helper_injection(mut self, skip: bool) -> Self { |
102 |
| - self.inject_helpers = !skip; |
103 |
| - self |
104 |
| - } |
105 |
| - |
106 |
| - pub fn minify(mut self, options: Option<JsMinifyOptions>) -> Self { |
107 |
| - self.minify = options; |
108 |
| - self |
109 |
| - } |
110 |
| - |
111 |
| - /// Note: fixer is enabled by default. |
112 |
| - pub fn fixer(mut self, enable: bool) -> Self { |
113 |
| - self.fixer = enable; |
114 |
| - self |
115 |
| - } |
116 |
| - |
117 |
| - /// Note: hygiene is enabled by default. |
118 |
| - /// |
119 |
| - /// If you pass [None] to this method, the `hygiene` pass will be disabled. |
120 |
| - pub fn hygiene(mut self, config: Option<hygiene::Config>) -> Self { |
121 |
| - self.hygiene = config; |
122 |
| - self |
123 |
| - } |
124 |
| - |
125 |
| - pub fn const_modules( |
126 |
| - self, |
127 |
| - globals: FxHashMap<Atom, FxHashMap<Atom, String>>, |
128 |
| - ) -> PassBuilder<'a, 'b, (P, impl Pass)> { |
129 |
| - let cm = self.cm.clone(); |
130 |
| - self.then(const_modules(cm, globals)) |
131 |
| - } |
132 |
| - |
133 |
| - pub fn inline_globals(self, c: GlobalPassOption) -> PassBuilder<'a, 'b, (P, impl Pass)> { |
134 |
| - let pass = c.build(self.cm, self.handler, self.unresolved_mark); |
135 |
| - self.then(pass) |
136 |
| - } |
137 |
| - |
138 |
| - pub fn target(mut self, target: EsVersion) -> Self { |
139 |
| - self.target = target; |
140 |
| - self |
141 |
| - } |
142 |
| - |
143 |
| - pub fn preset_env(mut self, env: Option<swc_ecma_preset_env::Config>) -> Self { |
144 |
| - self.env = env.map(Into::into); |
145 |
| - self |
146 |
| - } |
147 |
| - |
148 |
| - pub fn regenerator(mut self, config: regenerator::Config) -> Self { |
149 |
| - self.regenerator = config; |
150 |
| - self |
151 |
| - } |
152 |
| - |
153 |
| - /// # Arguments |
154 |
| - /// ## module |
155 |
| - /// - Use `None` if you want swc to emit import statements. |
156 |
| - /// |
157 |
| - /// |
158 |
| - /// Returned pass includes |
159 |
| - /// |
160 |
| - /// - compatibility helper |
161 |
| - /// - module handler |
162 |
| - /// - helper injector |
163 |
| - /// - identifier hygiene handler if enabled |
164 |
| - /// - fixer if enabled |
165 |
| - pub fn finalize<'cmt>( |
166 |
| - self, |
167 |
| - _syntax: Syntax, |
168 |
| - module: Option<ModuleConfig>, |
169 |
| - comments: Option<&'cmt dyn Comments>, |
170 |
| - resolver: Option<(FileName, Arc<dyn ImportResolver>)>, |
171 |
| - ) -> impl 'cmt + Pass |
172 |
| - where |
173 |
| - P: 'cmt, |
174 |
| - { |
175 |
| - let (need_analyzer, import_interop, ignore_dynamic) = match module { |
176 |
| - Some(ModuleConfig::CommonJs(ref c)) => (true, c.import_interop(), c.ignore_dynamic), |
177 |
| - Some(ModuleConfig::Amd(ref c)) => { |
178 |
| - (true, c.config.import_interop(), c.config.ignore_dynamic) |
179 |
| - } |
180 |
| - Some(ModuleConfig::Umd(ref c)) => { |
181 |
| - (true, c.config.import_interop(), c.config.ignore_dynamic) |
182 |
| - } |
183 |
| - Some(ModuleConfig::SystemJs(_)) |
184 |
| - | Some(ModuleConfig::Es6(..)) |
185 |
| - | Some(ModuleConfig::NodeNext(..)) |
186 |
| - | None => (false, true.into(), true), |
187 |
| - }; |
188 |
| - |
189 |
| - let feature_config = self.env.as_ref().map(|e| e.get_feature_config()); |
190 |
| - |
191 |
| - // compat |
192 |
| - let compat_pass = { |
193 |
| - if let Some(env_config) = self.env { |
194 |
| - Either::Left(swc_ecma_preset_env::transform_from_env( |
195 |
| - self.unresolved_mark, |
196 |
| - comments, |
197 |
| - env_config, |
198 |
| - self.assumptions, |
199 |
| - )) |
200 |
| - } else { |
201 |
| - Either::Right(swc_ecma_preset_env::transform_from_es_version( |
202 |
| - self.unresolved_mark, |
203 |
| - comments, |
204 |
| - self.target, |
205 |
| - self.assumptions, |
206 |
| - self.loose, |
207 |
| - )) |
208 |
| - } |
209 |
| - }; |
210 |
| - |
211 |
| - let is_mangler_enabled = self |
212 |
| - .minify |
213 |
| - .as_ref() |
214 |
| - .map(|v| v.mangle.is_obj() || v.mangle.is_true()) |
215 |
| - .unwrap_or(false); |
216 |
| - |
217 |
| - ( |
218 |
| - self.pass, |
219 |
| - Optional::new( |
220 |
| - paren_remover(comments.map(|v| v as &dyn Comments)), |
221 |
| - self.fixer, |
222 |
| - ), |
223 |
| - compat_pass, |
224 |
| - // module / helper |
225 |
| - Optional::new( |
226 |
| - modules::import_analysis::import_analyzer(import_interop, ignore_dynamic), |
227 |
| - need_analyzer, |
228 |
| - ), |
229 |
| - Optional::new( |
230 |
| - helpers::inject_helpers(self.unresolved_mark), |
231 |
| - self.inject_helpers, |
232 |
| - ), |
233 |
| - ModuleConfig::build( |
234 |
| - self.cm.clone(), |
235 |
| - comments, |
236 |
| - module, |
237 |
| - self.unresolved_mark, |
238 |
| - resolver, |
239 |
| - |f| { |
240 |
| - feature_config |
241 |
| - .as_ref() |
242 |
| - .map_or_else(|| self.target.caniuse(f), |env| env.caniuse(f)) |
243 |
| - }, |
244 |
| - ), |
245 |
| - visit_mut_pass(MinifierPass { |
246 |
| - options: self.minify, |
247 |
| - cm: self.cm.clone(), |
248 |
| - comments, |
249 |
| - top_level_mark: self.top_level_mark, |
250 |
| - }), |
251 |
| - Optional::new( |
252 |
| - hygiene_with_config(swc_ecma_transforms_base::hygiene::Config { |
253 |
| - top_level_mark: self.top_level_mark, |
254 |
| - ..self.hygiene.clone().unwrap_or_default() |
255 |
| - }), |
256 |
| - self.hygiene.is_some() && !is_mangler_enabled, |
257 |
| - ), |
258 |
| - Optional::new(fixer(comments.map(|v| v as &dyn Comments)), self.fixer), |
259 |
| - ) |
260 |
| - } |
261 |
| -} |
| 7 | +use crate::config::JsMinifyOptions; |
262 | 8 |
|
263 |
| -struct MinifierPass<'a> { |
264 |
| - options: Option<JsMinifyOptions>, |
265 |
| - cm: Lrc<SourceMap>, |
266 |
| - comments: Option<&'a dyn Comments>, |
267 |
| - top_level_mark: Mark, |
| 9 | +pub struct MinifierPass<'a> { |
| 10 | + pub options: Option<JsMinifyOptions>, |
| 11 | + pub cm: Lrc<SourceMap>, |
| 12 | + pub comments: Option<&'a dyn Comments>, |
| 13 | + pub top_level_mark: Mark, |
268 | 14 | }
|
269 | 15 |
|
270 | 16 | impl VisitMut for MinifierPass<'_> {
|
|
0 commit comments