terser 5.4.0 → 5.6.0
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 +9 -0
- package/README.md +2 -2
- package/dist/bundle.min.js +313 -64
- package/lib/ast.js +47 -2
- package/lib/cli.js +4 -14
- package/lib/compress/index.js +6 -6
- package/lib/mozilla-ast.js +75 -6
- package/lib/output.js +67 -9
- package/lib/parse.js +71 -19
- package/lib/propmangle.js +33 -2
- package/lib/scope.js +4 -1
- package/lib/size.js +24 -0
- package/package.json +8 -8
- package/tools/terser.d.ts +1 -0
- package/dist/bundle.min.js.map +0 -1
package/lib/parse.js
CHANGED
@@ -65,8 +65,12 @@ import {
|
|
65
65
|
AST_Catch,
|
66
66
|
AST_Chain,
|
67
67
|
AST_ClassExpression,
|
68
|
+
AST_ClassPrivateProperty,
|
68
69
|
AST_ClassProperty,
|
69
70
|
AST_ConciseMethod,
|
71
|
+
AST_PrivateGetter,
|
72
|
+
AST_PrivateMethod,
|
73
|
+
AST_PrivateSetter,
|
70
74
|
AST_Conditional,
|
71
75
|
AST_Const,
|
72
76
|
AST_Continue,
|
@@ -80,6 +84,7 @@ import {
|
|
80
84
|
AST_Directive,
|
81
85
|
AST_Do,
|
82
86
|
AST_Dot,
|
87
|
+
AST_DotHash,
|
83
88
|
AST_EmptyStatement,
|
84
89
|
AST_Expansion,
|
85
90
|
AST_Export,
|
@@ -315,12 +320,14 @@ function is_identifier_char(ch) {
|
|
315
320
|
return UNICODE.ID_Continue.test(ch);
|
316
321
|
}
|
317
322
|
|
323
|
+
const BASIC_IDENT = /^[a-z_$][a-z0-9_$]*$/i;
|
324
|
+
|
318
325
|
function is_basic_identifier_string(str) {
|
319
|
-
return
|
326
|
+
return BASIC_IDENT.test(str);
|
320
327
|
}
|
321
328
|
|
322
329
|
function is_identifier_string(str, allow_surrogates) {
|
323
|
-
if (
|
330
|
+
if (BASIC_IDENT.test(str)) {
|
324
331
|
return true;
|
325
332
|
}
|
326
333
|
if (!allow_surrogates && /[\ud800-\udfff]/.test(str)) {
|
@@ -866,6 +873,11 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
866
873
|
: token("keyword", word);
|
867
874
|
}
|
868
875
|
|
876
|
+
function read_private_word() {
|
877
|
+
next();
|
878
|
+
return token("privatename", read_name());
|
879
|
+
}
|
880
|
+
|
869
881
|
function with_eof_error(eof_error, cont) {
|
870
882
|
return function(x) {
|
871
883
|
try {
|
@@ -935,6 +947,7 @@ function tokenizer($TEXT, filename, html5_comments, shebang) {
|
|
935
947
|
if (PUNC_CHARS.has(ch)) return token("punc", next());
|
936
948
|
if (OPERATOR_CHARS.has(ch)) return read_operator();
|
937
949
|
if (code == 92 || is_identifier_start(ch)) return read_word();
|
950
|
+
if (code == 35) return read_private_word();
|
938
951
|
break;
|
939
952
|
}
|
940
953
|
parse_error("Unexpected character '" + ch + "'");
|
@@ -1135,6 +1148,13 @@ function parse($TEXT, options) {
|
|
1135
1148
|
return S.in_async === S.in_function;
|
1136
1149
|
}
|
1137
1150
|
|
1151
|
+
function can_await() {
|
1152
|
+
return (
|
1153
|
+
S.in_async === S.in_function
|
1154
|
+
|| S.in_function === 0 && S.input.has_directive("use strict")
|
1155
|
+
);
|
1156
|
+
}
|
1157
|
+
|
1138
1158
|
function semicolon(optional) {
|
1139
1159
|
if (is("punc", ";")) next();
|
1140
1160
|
else if (!optional && !can_insert_semicolon()) unexpected();
|
@@ -1419,7 +1439,7 @@ function parse($TEXT, options) {
|
|
1419
1439
|
var for_await_error = "`for await` invalid in this context";
|
1420
1440
|
var await_tok = S.token;
|
1421
1441
|
if (await_tok.type == "name" && await_tok.value == "await") {
|
1422
|
-
if (!
|
1442
|
+
if (!can_await()) {
|
1423
1443
|
token_error(await_tok, for_await_error);
|
1424
1444
|
}
|
1425
1445
|
next();
|
@@ -1916,7 +1936,7 @@ function parse($TEXT, options) {
|
|
1916
1936
|
|
1917
1937
|
function _await_expression() {
|
1918
1938
|
// Previous token must be "await" and not be interpreted as an identifier
|
1919
|
-
if (!
|
1939
|
+
if (!can_await()) {
|
1920
1940
|
croak("Unexpected await expression outside async function",
|
1921
1941
|
S.prev.line, S.prev.col, S.prev.pos);
|
1922
1942
|
}
|
@@ -2536,6 +2556,7 @@ function parse($TEXT, options) {
|
|
2536
2556
|
}
|
2537
2557
|
return name;
|
2538
2558
|
};
|
2559
|
+
var privatename = start.type == "privatename";
|
2539
2560
|
var is_async = false;
|
2540
2561
|
var is_static = false;
|
2541
2562
|
var is_generator = false;
|
@@ -2543,16 +2564,19 @@ function parse($TEXT, options) {
|
|
2543
2564
|
if (is_class && name === "static" && !is("punc", "(")) {
|
2544
2565
|
is_static = true;
|
2545
2566
|
property_token = S.token;
|
2567
|
+
privatename = property_token.type == "privatename";
|
2546
2568
|
name = as_property_name();
|
2547
2569
|
}
|
2548
2570
|
if (name === "async" && !is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=")) {
|
2549
2571
|
is_async = true;
|
2550
2572
|
property_token = S.token;
|
2573
|
+
privatename = property_token.type == "privatename";
|
2551
2574
|
name = as_property_name();
|
2552
2575
|
}
|
2553
2576
|
if (name === null) {
|
2554
2577
|
is_generator = true;
|
2555
2578
|
property_token = S.token;
|
2579
|
+
privatename = property_token.type == "privatename";
|
2556
2580
|
name = as_property_name();
|
2557
2581
|
if (name === null) {
|
2558
2582
|
unexpected();
|
@@ -2560,7 +2584,10 @@ function parse($TEXT, options) {
|
|
2560
2584
|
}
|
2561
2585
|
if (is("punc", "(")) {
|
2562
2586
|
name = get_method_name_ast(name, start);
|
2563
|
-
|
2587
|
+
const AST_MethodVariant = privatename
|
2588
|
+
? AST_PrivateMethod
|
2589
|
+
: AST_ConciseMethod;
|
2590
|
+
var node = new AST_MethodVariant({
|
2564
2591
|
start : start,
|
2565
2592
|
static : is_static,
|
2566
2593
|
is_generator: is_generator,
|
@@ -2574,6 +2601,23 @@ function parse($TEXT, options) {
|
|
2574
2601
|
return node;
|
2575
2602
|
}
|
2576
2603
|
const setter_token = S.token;
|
2604
|
+
if ((name === "get" || name === "set") && setter_token.type === "privatename") {
|
2605
|
+
next();
|
2606
|
+
|
2607
|
+
const AST_AccessorVariant =
|
2608
|
+
name === "get"
|
2609
|
+
? AST_PrivateGetter
|
2610
|
+
: AST_PrivateSetter;
|
2611
|
+
|
2612
|
+
return new AST_AccessorVariant({
|
2613
|
+
start,
|
2614
|
+
static: is_static,
|
2615
|
+
key: get_method_name_ast(setter_token.value, start),
|
2616
|
+
value: create_accessor(),
|
2617
|
+
end: prev(),
|
2618
|
+
});
|
2619
|
+
}
|
2620
|
+
|
2577
2621
|
if (name == "get") {
|
2578
2622
|
if (!is("punc") || is("punc", "[")) {
|
2579
2623
|
name = get_method_name_ast(as_property_name(), start);
|
@@ -2606,9 +2650,12 @@ function parse($TEXT, options) {
|
|
2606
2650
|
const quote = key instanceof AST_SymbolClassProperty
|
2607
2651
|
? property_token.quote
|
2608
2652
|
: undefined;
|
2653
|
+
const AST_ClassPropertyVariant = privatename
|
2654
|
+
? AST_ClassPrivateProperty
|
2655
|
+
: AST_ClassProperty;
|
2609
2656
|
if (is("operator", "=")) {
|
2610
2657
|
next();
|
2611
|
-
return new
|
2658
|
+
return new AST_ClassPropertyVariant({
|
2612
2659
|
start,
|
2613
2660
|
static: is_static,
|
2614
2661
|
quote,
|
@@ -2616,8 +2663,14 @@ function parse($TEXT, options) {
|
|
2616
2663
|
value: expression(false),
|
2617
2664
|
end: prev()
|
2618
2665
|
});
|
2619
|
-
} else if (
|
2620
|
-
|
2666
|
+
} else if (
|
2667
|
+
is("name")
|
2668
|
+
|| is("privatename")
|
2669
|
+
|| is("operator", "*")
|
2670
|
+
|| is("punc", ";")
|
2671
|
+
|| is("punc", "}")
|
2672
|
+
) {
|
2673
|
+
return new AST_ClassPropertyVariant({
|
2621
2674
|
start,
|
2622
2675
|
static: is_static,
|
2623
2676
|
quote,
|
@@ -2856,6 +2909,7 @@ function parse($TEXT, options) {
|
|
2856
2909
|
}
|
2857
2910
|
/* falls through */
|
2858
2911
|
case "name":
|
2912
|
+
case "privatename":
|
2859
2913
|
case "string":
|
2860
2914
|
case "num":
|
2861
2915
|
case "big_int":
|
@@ -2870,7 +2924,7 @@ function parse($TEXT, options) {
|
|
2870
2924
|
|
2871
2925
|
function as_name() {
|
2872
2926
|
var tmp = S.token;
|
2873
|
-
if (tmp.type != "name") unexpected();
|
2927
|
+
if (tmp.type != "name" && tmp.type != "privatename") unexpected();
|
2874
2928
|
next();
|
2875
2929
|
return tmp.value;
|
2876
2930
|
}
|
@@ -2941,7 +2995,8 @@ function parse($TEXT, options) {
|
|
2941
2995
|
var start = expr.start;
|
2942
2996
|
if (is("punc", ".")) {
|
2943
2997
|
next();
|
2944
|
-
|
2998
|
+
const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
|
2999
|
+
return subscripts(new AST_DotVariant({
|
2945
3000
|
start : start,
|
2946
3001
|
expression : expr,
|
2947
3002
|
optional : false,
|
@@ -2992,8 +3047,9 @@ function parse($TEXT, options) {
|
|
2992
3047
|
annotate(call);
|
2993
3048
|
|
2994
3049
|
chain_contents = subscripts(call, true, true);
|
2995
|
-
} else if (is("name")) {
|
2996
|
-
|
3050
|
+
} else if (is("name") || is("privatename")) {
|
3051
|
+
const AST_DotVariant = is("privatename") ? AST_DotHash : AST_Dot;
|
3052
|
+
chain_contents = subscripts(new AST_DotVariant({
|
2997
3053
|
start,
|
2998
3054
|
expression: expr,
|
2999
3055
|
optional: true,
|
@@ -3064,13 +3120,9 @@ function parse($TEXT, options) {
|
|
3064
3120
|
|
3065
3121
|
var maybe_unary = function(allow_calls, allow_arrows) {
|
3066
3122
|
var start = S.token;
|
3067
|
-
if (start.type == "name" && start.value == "await") {
|
3068
|
-
|
3069
|
-
|
3070
|
-
return _await_expression();
|
3071
|
-
} else if (S.input.has_directive("use strict")) {
|
3072
|
-
token_error(S.token, "Unexpected await identifier inside strict mode");
|
3073
|
-
}
|
3123
|
+
if (start.type == "name" && start.value == "await" && can_await()) {
|
3124
|
+
next();
|
3125
|
+
return _await_expression();
|
3074
3126
|
}
|
3075
3127
|
if (is("operator") && UNARY_PREFIX.has(start.value)) {
|
3076
3128
|
next();
|
package/lib/propmangle.js
CHANGED
@@ -52,10 +52,13 @@ import { base54 } from "./scope.js";
|
|
52
52
|
import {
|
53
53
|
AST_Binary,
|
54
54
|
AST_Call,
|
55
|
+
AST_ClassPrivateProperty,
|
55
56
|
AST_Conditional,
|
56
57
|
AST_Dot,
|
58
|
+
AST_DotHash,
|
57
59
|
AST_ObjectKeyVal,
|
58
60
|
AST_ObjectProperty,
|
61
|
+
AST_PrivateMethod,
|
59
62
|
AST_Sequence,
|
60
63
|
AST_String,
|
61
64
|
AST_Sub,
|
@@ -155,7 +158,10 @@ function mangle_properties(ast, options) {
|
|
155
158
|
if (!options.builtins) find_builtins(reserved);
|
156
159
|
|
157
160
|
var cname = -1;
|
161
|
+
var cprivate = -1;
|
162
|
+
|
158
163
|
var cache;
|
164
|
+
var private_cache = new Map();
|
159
165
|
if (options.cache) {
|
160
166
|
cache = options.cache.props;
|
161
167
|
cache.forEach(function(mangled_name) {
|
@@ -178,12 +184,20 @@ function mangle_properties(ast, options) {
|
|
178
184
|
|
179
185
|
var names_to_mangle = new Set();
|
180
186
|
var unmangleable = new Set();
|
187
|
+
var private_properties = new Set();
|
181
188
|
|
182
189
|
var keep_quoted_strict = options.keep_quoted === "strict";
|
183
190
|
|
184
191
|
// step 1: find candidates to mangle
|
185
192
|
ast.walk(new TreeWalker(function(node) {
|
186
|
-
if (
|
193
|
+
if (
|
194
|
+
node instanceof AST_ClassPrivateProperty
|
195
|
+
|| node instanceof AST_PrivateMethod
|
196
|
+
) {
|
197
|
+
private_properties.add(node.key.name);
|
198
|
+
} else if (node instanceof AST_DotHash) {
|
199
|
+
private_properties.add(node.property);
|
200
|
+
} else if (node instanceof AST_ObjectKeyVal) {
|
187
201
|
if (typeof node.key == "string" &&
|
188
202
|
(!keep_quoted_strict || !node.quote)) {
|
189
203
|
add(node.key);
|
@@ -220,7 +234,14 @@ function mangle_properties(ast, options) {
|
|
220
234
|
|
221
235
|
// step 2: transform the tree, renaming properties
|
222
236
|
return ast.transform(new TreeTransformer(function(node) {
|
223
|
-
if (
|
237
|
+
if (
|
238
|
+
node instanceof AST_ClassPrivateProperty
|
239
|
+
|| node instanceof AST_PrivateMethod
|
240
|
+
) {
|
241
|
+
node.key.name = mangle_private(node.key.name);
|
242
|
+
} else if (node instanceof AST_DotHash) {
|
243
|
+
node.property = mangle_private(node.property);
|
244
|
+
} else if (node instanceof AST_ObjectKeyVal) {
|
224
245
|
if (typeof node.key == "string" &&
|
225
246
|
(!keep_quoted_strict || !node.quote)) {
|
226
247
|
node.key = mangle(node.key);
|
@@ -300,6 +321,16 @@ function mangle_properties(ast, options) {
|
|
300
321
|
return mangled;
|
301
322
|
}
|
302
323
|
|
324
|
+
function mangle_private(name) {
|
325
|
+
let mangled = private_cache.get(name);
|
326
|
+
if (!mangled) {
|
327
|
+
mangled = base54(++cprivate);
|
328
|
+
private_cache.set(name, mangled);
|
329
|
+
}
|
330
|
+
|
331
|
+
return mangled;
|
332
|
+
}
|
333
|
+
|
303
334
|
function mangleStrings(node) {
|
304
335
|
return node.transform(new TreeTransformer(function(node) {
|
305
336
|
if (node instanceof AST_Sequence) {
|
package/lib/scope.js
CHANGED
@@ -65,6 +65,7 @@ import {
|
|
65
65
|
AST_Defun,
|
66
66
|
AST_Destructuring,
|
67
67
|
AST_Dot,
|
68
|
+
AST_DotHash,
|
68
69
|
AST_Export,
|
69
70
|
AST_For,
|
70
71
|
AST_ForIn,
|
@@ -919,7 +920,9 @@ AST_Toplevel.DEFMETHOD("compute_char_frequency", function(options) {
|
|
919
920
|
if (this instanceof AST_Symbol && !this.unmangleable(options)) {
|
920
921
|
base54.consider(this.name, -1);
|
921
922
|
} else if (options.properties) {
|
922
|
-
if (this instanceof
|
923
|
+
if (this instanceof AST_DotHash) {
|
924
|
+
base54.consider("#" + this.property, -1);
|
925
|
+
} else if (this instanceof AST_Dot) {
|
923
926
|
base54.consider(this.property, -1);
|
924
927
|
} else if (this instanceof AST_Sub) {
|
925
928
|
skip_string(this.property);
|
package/lib/size.js
CHANGED
@@ -10,6 +10,7 @@ import {
|
|
10
10
|
AST_Call,
|
11
11
|
AST_Case,
|
12
12
|
AST_Class,
|
13
|
+
AST_ClassPrivateProperty,
|
13
14
|
AST_ClassProperty,
|
14
15
|
AST_ConciseMethod,
|
15
16
|
AST_Conditional,
|
@@ -22,6 +23,7 @@ import {
|
|
22
23
|
AST_Directive,
|
23
24
|
AST_Do,
|
24
25
|
AST_Dot,
|
26
|
+
AST_DotHash,
|
25
27
|
AST_EmptyStatement,
|
26
28
|
AST_Expansion,
|
27
29
|
AST_Export,
|
@@ -47,6 +49,9 @@ import {
|
|
47
49
|
AST_ObjectKeyVal,
|
48
50
|
AST_ObjectGetter,
|
49
51
|
AST_ObjectSetter,
|
52
|
+
AST_PrivateGetter,
|
53
|
+
AST_PrivateMethod,
|
54
|
+
AST_PrivateSetter,
|
50
55
|
AST_RegExp,
|
51
56
|
AST_Return,
|
52
57
|
AST_Sequence,
|
@@ -302,6 +307,13 @@ AST_Dot.prototype._size = function () {
|
|
302
307
|
return this.property.length + 1;
|
303
308
|
};
|
304
309
|
|
310
|
+
AST_DotHash.prototype._size = function () {
|
311
|
+
if (this.optional) {
|
312
|
+
return this.property.length + 3;
|
313
|
+
}
|
314
|
+
return this.property.length + 2;
|
315
|
+
};
|
316
|
+
|
305
317
|
AST_Sub.prototype._size = function () {
|
306
318
|
return this.optional ? 4 : 2;
|
307
319
|
};
|
@@ -369,6 +381,14 @@ AST_ConciseMethod.prototype._size = function () {
|
|
369
381
|
return static_size(this.static) + key_size(this.key) + lambda_modifiers(this);
|
370
382
|
};
|
371
383
|
|
384
|
+
AST_PrivateMethod.prototype._size = function () {
|
385
|
+
return AST_ConciseMethod.prototype._size.call(this) + 1;
|
386
|
+
};
|
387
|
+
|
388
|
+
AST_PrivateGetter.prototype._size = AST_PrivateSetter.prototype._size = function () {
|
389
|
+
return AST_ConciseMethod.prototype._size.call(this) + 4;
|
390
|
+
};
|
391
|
+
|
372
392
|
AST_Class.prototype._size = function () {
|
373
393
|
return (
|
374
394
|
(this.name ? 8 : 7)
|
@@ -384,6 +404,10 @@ AST_ClassProperty.prototype._size = function () {
|
|
384
404
|
);
|
385
405
|
};
|
386
406
|
|
407
|
+
AST_ClassPrivateProperty.prototype._size = function () {
|
408
|
+
return AST_ClassProperty.prototype._size.call(this) + 1;
|
409
|
+
};
|
410
|
+
|
387
411
|
AST_Symbol.prototype._size = function () {
|
388
412
|
return !mangle_options || this.definition().unmangleable(mangle_options)
|
389
413
|
? this.name.length
|
package/package.json
CHANGED
@@ -4,7 +4,7 @@
|
|
4
4
|
"homepage": "https://terser.org",
|
5
5
|
"author": "Mihai Bazon <mihai.bazon@gmail.com> (http://lisperator.net/)",
|
6
6
|
"license": "BSD-2-Clause",
|
7
|
-
"version": "5.
|
7
|
+
"version": "5.6.0",
|
8
8
|
"engines": {
|
9
9
|
"node": ">=10"
|
10
10
|
},
|
@@ -48,16 +48,16 @@
|
|
48
48
|
},
|
49
49
|
"devDependencies": {
|
50
50
|
"@ls-lint/ls-lint": "^1.9.2",
|
51
|
-
"acorn": "^
|
52
|
-
"astring": "^1.
|
53
|
-
"eslint": "^7.
|
51
|
+
"acorn": "^8.0.5",
|
52
|
+
"astring": "^1.6.2",
|
53
|
+
"eslint": "^7.19.0",
|
54
54
|
"eslump": "^2.0.0",
|
55
55
|
"esm": "^3.2.25",
|
56
|
-
"mocha": "^8.
|
56
|
+
"mocha": "^8.2.1",
|
57
57
|
"pre-commit": "^1.2.2",
|
58
|
-
"rimraf": "^3.0.
|
59
|
-
"rollup": "2.
|
60
|
-
"semver": "^7.
|
58
|
+
"rimraf": "^3.0.2",
|
59
|
+
"rollup": "2.38.4",
|
60
|
+
"semver": "^7.3.4"
|
61
61
|
},
|
62
62
|
"scripts": {
|
63
63
|
"test": "node test/compress.js && mocha test/mocha",
|
package/tools/terser.d.ts
CHANGED
@@ -96,6 +96,7 @@ export interface ManglePropertiesOptions {
|
|
96
96
|
|
97
97
|
export interface FormatOptions {
|
98
98
|
ascii_only?: boolean;
|
99
|
+
/** @deprecated Not implemented anymore */
|
99
100
|
beautify?: boolean;
|
100
101
|
braces?: boolean;
|
101
102
|
comments?: boolean | 'all' | 'some' | RegExp | ( (node: any, comment: {
|