terser 5.5.0 → 5.6.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/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,
@@ -87,6 +92,12 @@ AST_Node.prototype.size = function (compressor, stack) {
87
92
  let size = 0;
88
93
  walk_parent(this, (node, info) => {
89
94
  size += node._size(info);
95
+
96
+ // Braceless arrow functions have fake "return" statements
97
+ if (node instanceof AST_Arrow && node.is_braceless()) {
98
+ size += node.body[0].value._size(info);
99
+ return true;
100
+ }
90
101
  }, stack || (compressor && compressor.stack));
91
102
 
92
103
  // just to save a bit of memory
@@ -131,7 +142,6 @@ AST_With.prototype._size = () => 6;
131
142
 
132
143
  AST_Expansion.prototype._size = () => 3;
133
144
 
134
- /*#__INLINE__*/
135
145
  const lambda_modifiers = func =>
136
146
  (func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
137
147
 
@@ -160,7 +170,9 @@ AST_Arrow.prototype._size = function () {
160
170
  args_and_arrow += 2;
161
171
  }
162
172
 
163
- return lambda_modifiers(this) + args_and_arrow + (Array.isArray(this.body) ? list_overhead(this.body) : this.body._size());
173
+ const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2;
174
+
175
+ return lambda_modifiers(this) + args_and_arrow + body_overhead;
164
176
  };
165
177
 
166
178
  AST_Destructuring.prototype._size = () => 2;
@@ -302,6 +314,13 @@ AST_Dot.prototype._size = function () {
302
314
  return this.property.length + 1;
303
315
  };
304
316
 
317
+ AST_DotHash.prototype._size = function () {
318
+ if (this.optional) {
319
+ return this.property.length + 3;
320
+ }
321
+ return this.property.length + 2;
322
+ };
323
+
305
324
  AST_Sub.prototype._size = function () {
306
325
  return this.optional ? 4 : 2;
307
326
  };
@@ -369,6 +388,14 @@ AST_ConciseMethod.prototype._size = function () {
369
388
  return static_size(this.static) + key_size(this.key) + lambda_modifiers(this);
370
389
  };
371
390
 
391
+ AST_PrivateMethod.prototype._size = function () {
392
+ return AST_ConciseMethod.prototype._size.call(this) + 1;
393
+ };
394
+
395
+ AST_PrivateGetter.prototype._size = AST_PrivateSetter.prototype._size = function () {
396
+ return AST_ConciseMethod.prototype._size.call(this) + 4;
397
+ };
398
+
372
399
  AST_Class.prototype._size = function () {
373
400
  return (
374
401
  (this.name ? 8 : 7)
@@ -384,6 +411,10 @@ AST_ClassProperty.prototype._size = function () {
384
411
  );
385
412
  };
386
413
 
414
+ AST_ClassPrivateProperty.prototype._size = function () {
415
+ return AST_ClassProperty.prototype._size.call(this) + 1;
416
+ };
417
+
387
418
  AST_Symbol.prototype._size = function () {
388
419
  return !mangle_options || this.definition().unmangleable(mangle_options)
389
420
  ? this.name.length
@@ -235,6 +235,7 @@ function keep_name(keep_setting, name) {
235
235
  }
236
236
 
237
237
  var lineTerminatorEscape = {
238
+ "\0": "0",
238
239
  "\n": "n",
239
240
  "\r": "r",
240
241
  "\u2028": "u2028",
@@ -242,7 +243,8 @@ var lineTerminatorEscape = {
242
243
  };
243
244
  function regexp_source_fix(source) {
244
245
  // V8 does not escape line terminators in regexp patterns in node 12
245
- return source.replace(/[\n\r\u2028\u2029]/g, function (match, offset) {
246
+ // We'll also remove literal \0
247
+ return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) {
246
248
  var escaped = source[offset - 1] == "\\"
247
249
  && (source[offset - 2] != "\\"
248
250
  || /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
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.5.0",
7
+ "version": "5.6.1",
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/domprops.js CHANGED
@@ -4120,6 +4120,7 @@ export var domprops = [
4120
4120
  "exponent",
4121
4121
  "exponentialRampToValueAtTime",
4122
4122
  "exportKey",
4123
+ "exports",
4123
4124
  "extend",
4124
4125
  "extensions",
4125
4126
  "extentNode",
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: {