terser 5.13.0 → 5.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +5 -0
- package/dist/bundle.min.js +2645 -2531
- package/lib/ast.js +24 -0
- package/lib/compress/common.js +48 -0
- package/lib/compress/index.js +23 -546
- package/lib/compress/inline.js +641 -0
- package/lib/compress/tighten-body.js +1 -1
- package/lib/parse.js +58 -56
- package/lib/size.js +6 -8
- package/package.json +1 -1
package/lib/ast.js
CHANGED
@@ -2869,6 +2869,21 @@ function walk(node, cb, to_visit = [node]) {
|
|
2869
2869
|
return false;
|
2870
2870
|
}
|
2871
2871
|
|
2872
|
+
/**
|
2873
|
+
* Walks an AST node and its children.
|
2874
|
+
*
|
2875
|
+
* {cb} can return `walk_abort` to interrupt the walk.
|
2876
|
+
*
|
2877
|
+
* @param node
|
2878
|
+
* @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)}
|
2879
|
+
*
|
2880
|
+
* @returns {boolean} whether the walk was aborted
|
2881
|
+
*
|
2882
|
+
* @example
|
2883
|
+
* const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => {
|
2884
|
+
* if (some_cond(node, parent())) return walk_abort
|
2885
|
+
* });
|
2886
|
+
*/
|
2872
2887
|
function walk_parent(node, cb, initial_stack) {
|
2873
2888
|
const to_visit = [node];
|
2874
2889
|
const push = to_visit.push.bind(to_visit);
|
@@ -2987,6 +3002,15 @@ class TreeWalker {
|
|
2987
3002
|
}
|
2988
3003
|
}
|
2989
3004
|
|
3005
|
+
find_scope() {
|
3006
|
+
for (let i = 0;;i++) {
|
3007
|
+
const p = this.parent(i);
|
3008
|
+
if (p instanceof AST_Toplevel) return p;
|
3009
|
+
if (p instanceof AST_Lambda) return p;
|
3010
|
+
if (p.block_scope) return p.block_scope;
|
3011
|
+
}
|
3012
|
+
}
|
3013
|
+
|
2990
3014
|
has_directive(type) {
|
2991
3015
|
var dir = this.directives[type];
|
2992
3016
|
if (dir) return dir;
|
package/lib/compress/common.js
CHANGED
@@ -80,9 +80,13 @@ import {
|
|
80
80
|
AST_Undefined,
|
81
81
|
|
82
82
|
TreeWalker,
|
83
|
+
walk,
|
84
|
+
walk_abort,
|
85
|
+
walk_parent,
|
83
86
|
} from "../ast.js";
|
84
87
|
import { make_node, regexp_source_fix, string_template, makePredicate } from "../utils/index.js";
|
85
88
|
import { first_in_statement } from "../utils/first_in_statement.js";
|
89
|
+
import { has_flag, TOP } from "./compressor-flags.js";
|
86
90
|
|
87
91
|
export function merge_sequence(array, node) {
|
88
92
|
if (node instanceof AST_Sequence) {
|
@@ -244,6 +248,13 @@ export function is_iife_call(node) {
|
|
244
248
|
return node.expression instanceof AST_Function || is_iife_call(node.expression);
|
245
249
|
}
|
246
250
|
|
251
|
+
export function is_empty(thing) {
|
252
|
+
if (thing === null) return true;
|
253
|
+
if (thing instanceof AST_EmptyStatement) return true;
|
254
|
+
if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
|
255
|
+
return false;
|
256
|
+
}
|
257
|
+
|
247
258
|
export const identifier_atom = makePredicate("Infinity NaN undefined");
|
248
259
|
export function is_identifier_atom(node) {
|
249
260
|
return node instanceof AST_Infinity
|
@@ -281,6 +292,34 @@ export function as_statement_array(thing) {
|
|
281
292
|
throw new Error("Can't convert thing to statement array");
|
282
293
|
}
|
283
294
|
|
295
|
+
export function is_reachable(scope_node, defs) {
|
296
|
+
const find_ref = node => {
|
297
|
+
if (node instanceof AST_SymbolRef && defs.includes(node.definition())) {
|
298
|
+
return walk_abort;
|
299
|
+
}
|
300
|
+
};
|
301
|
+
|
302
|
+
return walk_parent(scope_node, (node, info) => {
|
303
|
+
if (node instanceof AST_Scope && node !== scope_node) {
|
304
|
+
var parent = info.parent();
|
305
|
+
|
306
|
+
if (
|
307
|
+
parent instanceof AST_Call
|
308
|
+
&& parent.expression === node
|
309
|
+
// Async/Generators aren't guaranteed to sync evaluate all of
|
310
|
+
// their body steps, so it's possible they close over the variable.
|
311
|
+
&& !(node.async || node.is_generator)
|
312
|
+
) {
|
313
|
+
return;
|
314
|
+
}
|
315
|
+
|
316
|
+
if (walk(node, find_ref)) return walk_abort;
|
317
|
+
|
318
|
+
return true;
|
319
|
+
}
|
320
|
+
});
|
321
|
+
}
|
322
|
+
|
284
323
|
/** Check if a ref refers to the name of a function/class it's defined within */
|
285
324
|
export function is_recursive_ref(compressor, def) {
|
286
325
|
var node;
|
@@ -294,3 +333,12 @@ export function is_recursive_ref(compressor, def) {
|
|
294
333
|
}
|
295
334
|
return false;
|
296
335
|
}
|
336
|
+
|
337
|
+
// TODO this only works with AST_Defun, shouldn't it work for other ways of defining functions?
|
338
|
+
export function retain_top_func(fn, compressor) {
|
339
|
+
return compressor.top_retain
|
340
|
+
&& fn instanceof AST_Defun
|
341
|
+
&& has_flag(fn, TOP)
|
342
|
+
&& fn.name
|
343
|
+
&& compressor.top_retain(fn.name);
|
344
|
+
}
|