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/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 /^[a-z_$][a-z0-9_$]*$/i.test(str);
326
+ return BASIC_IDENT.test(str);
320
327
  }
321
328
 
322
329
  function is_identifier_string(str, allow_surrogates) {
323
- if (/^[a-z_$][a-z0-9_$]*$/i.test(str)) {
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 (!is_in_async()) {
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 (!is_in_async()) {
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
- var node = new AST_ConciseMethod({
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 AST_ClassProperty({
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 (is("name") || is("punc", ";") || is("punc", "}")) {
2620
- return new AST_ClassProperty({
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
- return subscripts(new AST_Dot({
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
- chain_contents = subscripts(new AST_Dot({
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
- if (is_in_async()) {
3069
- next();
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 (node instanceof AST_ObjectKeyVal) {
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 (node instanceof AST_ObjectKeyVal) {
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 AST_Dot) {
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.4.0",
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": "^7.4.0",
52
- "astring": "^1.4.1",
53
- "eslint": "^7.0.0",
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.0.0",
56
+ "mocha": "^8.2.1",
57
57
  "pre-commit": "^1.2.2",
58
- "rimraf": "^3.0.0",
59
- "rollup": "2.0.6",
60
- "semver": "^7.1.3"
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: {