terser 5.13.0 → 5.14.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 +16 -0
- package/dist/bundle.min.js +2803 -2606
- package/lib/ast.js +34 -11
- 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/minify.js +47 -14
- package/lib/output.js +17 -0
- package/lib/parse.js +67 -64
- package/lib/size.js +6 -8
- package/lib/sourcemap.js +60 -26
- package/package.json +5 -3
- package/tools/domprops.js +1 -0
- package/tools/terser.d.ts +6 -3
package/lib/ast.js
CHANGED
@@ -93,6 +93,7 @@ const set_tok_flag = (tok, flag, truth) => {
|
|
93
93
|
const TOK_FLAG_NLB = 0b0001;
|
94
94
|
const TOK_FLAG_QUOTE_SINGLE = 0b0010;
|
95
95
|
const TOK_FLAG_QUOTE_EXISTS = 0b0100;
|
96
|
+
const TOK_FLAG_TEMPLATE_END = 0b1000;
|
96
97
|
|
97
98
|
class AST_Token {
|
98
99
|
constructor(type, value, line, col, pos, nlb, comments_before, comments_after, file) {
|
@@ -128,6 +129,14 @@ class AST_Token {
|
|
128
129
|
set_tok_flag(this, TOK_FLAG_QUOTE_SINGLE, quote_type === "'");
|
129
130
|
set_tok_flag(this, TOK_FLAG_QUOTE_EXISTS, !!quote_type);
|
130
131
|
}
|
132
|
+
|
133
|
+
get template_end() {
|
134
|
+
return has_tok_flag(this, TOK_FLAG_TEMPLATE_END);
|
135
|
+
}
|
136
|
+
|
137
|
+
set template_end(new_template_end) {
|
138
|
+
set_tok_flag(this, TOK_FLAG_TEMPLATE_END, new_template_end);
|
139
|
+
}
|
131
140
|
}
|
132
141
|
|
133
142
|
var AST_Node = DEFNODE("Node", "start end", function AST_Node(props) {
|
@@ -552,11 +561,10 @@ var AST_With = DEFNODE("With", "expression", function AST_With(props) {
|
|
552
561
|
|
553
562
|
var AST_Scope = DEFNODE(
|
554
563
|
"Scope",
|
555
|
-
"variables
|
564
|
+
"variables uses_with uses_eval parent_scope enclosed cname",
|
556
565
|
function AST_Scope(props) {
|
557
566
|
if (props) {
|
558
567
|
this.variables = props.variables;
|
559
|
-
this.functions = props.functions;
|
560
568
|
this.uses_with = props.uses_with;
|
561
569
|
this.uses_eval = props.uses_eval;
|
562
570
|
this.parent_scope = props.parent_scope;
|
@@ -612,7 +620,6 @@ var AST_Toplevel = DEFNODE("Toplevel", "globals", function AST_Toplevel(props) {
|
|
612
620
|
if (props) {
|
613
621
|
this.globals = props.globals;
|
614
622
|
this.variables = props.variables;
|
615
|
-
this.functions = props.functions;
|
616
623
|
this.uses_with = props.uses_with;
|
617
624
|
this.uses_eval = props.uses_eval;
|
618
625
|
this.parent_scope = props.parent_scope;
|
@@ -694,7 +701,6 @@ var AST_Lambda = DEFNODE(
|
|
694
701
|
this.is_generator = props.is_generator;
|
695
702
|
this.async = props.async;
|
696
703
|
this.variables = props.variables;
|
697
|
-
this.functions = props.functions;
|
698
704
|
this.uses_with = props.uses_with;
|
699
705
|
this.uses_eval = props.uses_eval;
|
700
706
|
this.parent_scope = props.parent_scope;
|
@@ -774,7 +780,6 @@ var AST_Accessor = DEFNODE("Accessor", null, function AST_Accessor(props) {
|
|
774
780
|
this.is_generator = props.is_generator;
|
775
781
|
this.async = props.async;
|
776
782
|
this.variables = props.variables;
|
777
|
-
this.functions = props.functions;
|
778
783
|
this.uses_with = props.uses_with;
|
779
784
|
this.uses_eval = props.uses_eval;
|
780
785
|
this.parent_scope = props.parent_scope;
|
@@ -799,7 +804,6 @@ var AST_Function = DEFNODE("Function", null, function AST_Function(props) {
|
|
799
804
|
this.is_generator = props.is_generator;
|
800
805
|
this.async = props.async;
|
801
806
|
this.variables = props.variables;
|
802
|
-
this.functions = props.functions;
|
803
807
|
this.uses_with = props.uses_with;
|
804
808
|
this.uses_eval = props.uses_eval;
|
805
809
|
this.parent_scope = props.parent_scope;
|
@@ -824,7 +828,6 @@ var AST_Arrow = DEFNODE("Arrow", null, function AST_Arrow(props) {
|
|
824
828
|
this.is_generator = props.is_generator;
|
825
829
|
this.async = props.async;
|
826
830
|
this.variables = props.variables;
|
827
|
-
this.functions = props.functions;
|
828
831
|
this.uses_with = props.uses_with;
|
829
832
|
this.uses_eval = props.uses_eval;
|
830
833
|
this.parent_scope = props.parent_scope;
|
@@ -849,7 +852,6 @@ var AST_Defun = DEFNODE("Defun", null, function AST_Defun(props) {
|
|
849
852
|
this.is_generator = props.is_generator;
|
850
853
|
this.async = props.async;
|
851
854
|
this.variables = props.variables;
|
852
|
-
this.functions = props.functions;
|
853
855
|
this.uses_with = props.uses_with;
|
854
856
|
this.uses_eval = props.uses_eval;
|
855
857
|
this.parent_scope = props.parent_scope;
|
@@ -2161,7 +2163,6 @@ var AST_Class = DEFNODE("Class", "name extends properties", function AST_Class(p
|
|
2161
2163
|
this.extends = props.extends;
|
2162
2164
|
this.properties = props.properties;
|
2163
2165
|
this.variables = props.variables;
|
2164
|
-
this.functions = props.functions;
|
2165
2166
|
this.uses_with = props.uses_with;
|
2166
2167
|
this.uses_eval = props.uses_eval;
|
2167
2168
|
this.parent_scope = props.parent_scope;
|
@@ -2255,7 +2256,6 @@ var AST_DefClass = DEFNODE("DefClass", null, function AST_DefClass(props) {
|
|
2255
2256
|
this.extends = props.extends;
|
2256
2257
|
this.properties = props.properties;
|
2257
2258
|
this.variables = props.variables;
|
2258
|
-
this.functions = props.functions;
|
2259
2259
|
this.uses_with = props.uses_with;
|
2260
2260
|
this.uses_eval = props.uses_eval;
|
2261
2261
|
this.parent_scope = props.parent_scope;
|
@@ -2278,7 +2278,6 @@ var AST_ClassExpression = DEFNODE("ClassExpression", null, function AST_ClassExp
|
|
2278
2278
|
this.extends = props.extends;
|
2279
2279
|
this.properties = props.properties;
|
2280
2280
|
this.variables = props.variables;
|
2281
|
-
this.functions = props.functions;
|
2282
2281
|
this.uses_with = props.uses_with;
|
2283
2282
|
this.uses_eval = props.uses_eval;
|
2284
2283
|
this.parent_scope = props.parent_scope;
|
@@ -2869,6 +2868,21 @@ function walk(node, cb, to_visit = [node]) {
|
|
2869
2868
|
return false;
|
2870
2869
|
}
|
2871
2870
|
|
2871
|
+
/**
|
2872
|
+
* Walks an AST node and its children.
|
2873
|
+
*
|
2874
|
+
* {cb} can return `walk_abort` to interrupt the walk.
|
2875
|
+
*
|
2876
|
+
* @param node
|
2877
|
+
* @param cb {(node, info: { parent: (nth) => any }) => (boolean | undefined)}
|
2878
|
+
*
|
2879
|
+
* @returns {boolean} whether the walk was aborted
|
2880
|
+
*
|
2881
|
+
* @example
|
2882
|
+
* const found_some_cond = walk_parent(my_ast_node, (node, { parent }) => {
|
2883
|
+
* if (some_cond(node, parent())) return walk_abort
|
2884
|
+
* });
|
2885
|
+
*/
|
2872
2886
|
function walk_parent(node, cb, initial_stack) {
|
2873
2887
|
const to_visit = [node];
|
2874
2888
|
const push = to_visit.push.bind(to_visit);
|
@@ -2987,6 +3001,15 @@ class TreeWalker {
|
|
2987
3001
|
}
|
2988
3002
|
}
|
2989
3003
|
|
3004
|
+
find_scope() {
|
3005
|
+
for (let i = 0;;i++) {
|
3006
|
+
const p = this.parent(i);
|
3007
|
+
if (p instanceof AST_Toplevel) return p;
|
3008
|
+
if (p instanceof AST_Lambda) return p;
|
3009
|
+
if (p.block_scope) return p.block_scope;
|
3010
|
+
}
|
3011
|
+
}
|
3012
|
+
|
2990
3013
|
has_directive(type) {
|
2991
3014
|
var dir = this.directives[type];
|
2992
3015
|
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
|
+
}
|