terser 5.31.0 → 5.31.2

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 CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.31.2
4
+ - drop_unused: scan variables in self-referential class declarations that contain side effects.
5
+ - Don't add parens to arrow function when it's the default for an argument (#1540)
6
+ - Update domprops (#1538)
7
+
8
+ ## v5.31.1
9
+ - Allow drop-unused to drop the whole assignment (not just the assigned name) in more situations, in order to avoid duplication of long strings.
10
+
3
11
  ## v5.31.0
4
12
  - Sync up property mangler exceptions with current contents of Firefox and Chrome environments
5
13
  - Add more webcomponent properties to property mangler exceptions (#1525)
@@ -2,7 +2,7 @@
2
2
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@jridgewell/source-map')) :
3
3
  typeof define === 'function' && define.amd ? define(['exports', '@jridgewell/source-map'], factory) :
4
4
  (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Terser = {}, global.sourceMap));
5
- })(this, (function (exports, sourceMap) { 'use strict';
5
+ }(this, (function (exports, sourceMap) { 'use strict';
6
6
 
7
7
  /***********************************************************************
8
8
 
@@ -10276,7 +10276,9 @@ function OutputStream(options) {
10276
10276
  AST_Arrow.DEFMETHOD("_do_print", function(output) {
10277
10277
  var self = this;
10278
10278
  var parent = output.parent();
10279
- var needs_parens = (parent instanceof AST_Binary && !(parent instanceof AST_Assign)) ||
10279
+ var needs_parens = (parent instanceof AST_Binary &&
10280
+ !(parent instanceof AST_Assign) &&
10281
+ !(parent instanceof AST_DefaultAssign)) ||
10280
10282
  parent instanceof AST_Unary ||
10281
10283
  (parent instanceof AST_Call && self === parent.expression);
10282
10284
  if (needs_parens) { output.print("("); }
@@ -13159,7 +13161,17 @@ function has_break_or_continue(loop, parent) {
13159
13161
  // func(something) because that changes the meaning of
13160
13162
  // the func (becomes lexical instead of global).
13161
13163
  function maintain_this_binding(parent, orig, val) {
13162
- if (
13164
+ if (requires_sequence_to_maintain_binding(parent, orig, val)) {
13165
+ const zero = make_node(AST_Number, orig, { value: 0 });
13166
+ return make_sequence(orig, [ zero, val ]);
13167
+ } else {
13168
+ return val;
13169
+ }
13170
+ }
13171
+
13172
+ /** Detect (1, x.noThis)(), (0, eval)(), which need sequences */
13173
+ function requires_sequence_to_maintain_binding(parent, orig, val) {
13174
+ return (
13163
13175
  parent instanceof AST_UnaryPrefix && parent.operator == "delete"
13164
13176
  || parent instanceof AST_Call && parent.expression === orig
13165
13177
  && (
@@ -13167,12 +13179,7 @@ function maintain_this_binding(parent, orig, val) {
13167
13179
  || val instanceof AST_PropAccess
13168
13180
  || val instanceof AST_SymbolRef && val.name == "eval"
13169
13181
  )
13170
- ) {
13171
- const zero = make_node(AST_Number, orig, { value: 0 });
13172
- return make_sequence(orig, [ zero, val ]);
13173
- } else {
13174
- return val;
13175
- }
13182
+ );
13176
13183
  }
13177
13184
 
13178
13185
  function is_func_expr(node) {
@@ -15267,7 +15274,6 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15267
15274
  }
15268
15275
  var var_defs_by_id = new Map();
15269
15276
  var initializations = new Map();
15270
- var self_referential_classes = new Set();
15271
15277
 
15272
15278
  // pass 1: find out which symbols are directly used in
15273
15279
  // this scope (not in nested scopes).
@@ -15282,8 +15288,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15282
15288
  }
15283
15289
  if (node === self) return;
15284
15290
  if (node instanceof AST_Class && node.has_side_effects(compressor)) {
15285
- if (node.is_self_referential()) self_referential_classes.add(node);
15286
- node.visit_nondeferred_class_parts(tw);
15291
+ if (node.is_self_referential()) {
15292
+ descend();
15293
+ } else {
15294
+ node.visit_nondeferred_class_parts(tw);
15295
+ }
15287
15296
  }
15288
15297
  if (node instanceof AST_Defun || node instanceof AST_DefClass) {
15289
15298
  var node_def = node.name.definition();
@@ -15347,9 +15356,6 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15347
15356
  init.walk(tw);
15348
15357
  });
15349
15358
  });
15350
- self_referential_classes.forEach(function (cls) {
15351
- cls.walk(tw);
15352
- });
15353
15359
  // pass 3: we should drop declarations not in_use
15354
15360
  var tt = new TreeTransformer(
15355
15361
  function before(node, descend, in_list) {
@@ -15361,7 +15367,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15361
15367
  var in_use = in_use_ids.has(def.id);
15362
15368
  if (node instanceof AST_Assign) {
15363
15369
  if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
15364
- return maintain_this_binding(parent, node, node.right.transform(tt));
15370
+ const assignee = node.right.transform(tt);
15371
+ if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) {
15372
+ return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
15373
+ }
15374
+ return maintain_this_binding(parent, node, assignee);
15365
15375
  }
15366
15376
  } else if (!in_use) {
15367
15377
  return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
@@ -15568,6 +15578,14 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15568
15578
  scope = save_scope;
15569
15579
  return node;
15570
15580
  }
15581
+ },
15582
+ function after(node, in_list) {
15583
+ if (node instanceof AST_Sequence) {
15584
+ switch (node.expressions.length) {
15585
+ case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
15586
+ case 1: return node.expressions[0];
15587
+ }
15588
+ }
15571
15589
  }
15572
15590
  );
15573
15591
 
@@ -15614,6 +15632,45 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
15614
15632
  }
15615
15633
  });
15616
15634
 
15635
+ /**
15636
+ * Check if a node may be used by the expression it's in
15637
+ * void (0, 1, {node}, 2) -> false
15638
+ * console.log(0, {node}) -> true
15639
+ */
15640
+ function is_used_in_expression(tw) {
15641
+ for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) {
15642
+ if (parent instanceof AST_Sequence) {
15643
+ const nth_expression = parent.expressions.indexOf(node);
15644
+ if (nth_expression !== parent.expressions.length - 1) {
15645
+ // Detect (0, x.noThis)() constructs
15646
+ const grandparent = tw.parent(p + 2);
15647
+ if (
15648
+ parent.expressions.length > 2
15649
+ || parent.expressions.length === 1
15650
+ || !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1])
15651
+ ) {
15652
+ return false;
15653
+ }
15654
+ return true;
15655
+ } else {
15656
+ continue;
15657
+ }
15658
+ }
15659
+ if (parent instanceof AST_Unary) {
15660
+ const op = parent.operator;
15661
+ if (op === "void") {
15662
+ return false;
15663
+ }
15664
+ if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") {
15665
+ continue;
15666
+ }
15667
+ }
15668
+ return true;
15669
+ }
15670
+
15671
+ return true;
15672
+ }
15673
+
15617
15674
  /***********************************************************************
15618
15675
 
15619
15676
  A JavaScript tokenizer / parser / beautifier / compressor.
@@ -30723,6 +30780,7 @@ var domprops = [
30723
30780
  "uint32",
30724
30781
  "uint8",
30725
30782
  "uint8Clamped",
30783
+ "unadjustedMovement",
30726
30784
  "unclippedDepth",
30727
30785
  "unconfigure",
30728
30786
  "undefined",
@@ -32483,4 +32541,4 @@ exports._run_cli = run_cli;
32483
32541
  exports.minify = minify;
32484
32542
  exports.minify_sync = minify_sync;
32485
32543
 
32486
- }));
32544
+ })));
@@ -226,7 +226,17 @@ export function has_break_or_continue(loop, parent) {
226
226
  // func(something) because that changes the meaning of
227
227
  // the func (becomes lexical instead of global).
228
228
  export function maintain_this_binding(parent, orig, val) {
229
- if (
229
+ if (requires_sequence_to_maintain_binding(parent, orig, val)) {
230
+ const zero = make_node(AST_Number, orig, { value: 0 });
231
+ return make_sequence(orig, [ zero, val ]);
232
+ } else {
233
+ return val;
234
+ }
235
+ }
236
+
237
+ /** Detect (1, x.noThis)(), (0, eval)(), which need sequences */
238
+ export function requires_sequence_to_maintain_binding(parent, orig, val) {
239
+ return (
230
240
  parent instanceof AST_UnaryPrefix && parent.operator == "delete"
231
241
  || parent instanceof AST_Call && parent.expression === orig
232
242
  && (
@@ -234,12 +244,7 @@ export function maintain_this_binding(parent, orig, val) {
234
244
  || val instanceof AST_PropAccess
235
245
  || val instanceof AST_SymbolRef && val.name == "eval"
236
246
  )
237
- ) {
238
- const zero = make_node(AST_Number, orig, { value: 0 });
239
- return make_sequence(orig, [ zero, val ]);
240
- } else {
241
- return val;
242
- }
247
+ );
243
248
  }
244
249
 
245
250
  export function is_func_expr(node) {
@@ -63,6 +63,7 @@ import {
63
63
  AST_Lambda,
64
64
  AST_Number,
65
65
  AST_Scope,
66
+ AST_Sequence,
66
67
  AST_SimpleStatement,
67
68
  AST_SymbolBlockDeclaration,
68
69
  AST_SymbolCatch,
@@ -101,6 +102,7 @@ import {
101
102
  is_empty,
102
103
  is_ref_of,
103
104
  can_be_evicted_from_block,
105
+ requires_sequence_to_maintain_binding,
104
106
  } from "./common.js";
105
107
 
106
108
  const r_keep_assign = /keep_assign/;
@@ -137,7 +139,6 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
137
139
  }
138
140
  var var_defs_by_id = new Map();
139
141
  var initializations = new Map();
140
- var self_referential_classes = new Set();
141
142
 
142
143
  // pass 1: find out which symbols are directly used in
143
144
  // this scope (not in nested scopes).
@@ -152,8 +153,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
152
153
  }
153
154
  if (node === self) return;
154
155
  if (node instanceof AST_Class && node.has_side_effects(compressor)) {
155
- if (node.is_self_referential()) self_referential_classes.add(node);
156
- node.visit_nondeferred_class_parts(tw);
156
+ if (node.is_self_referential()) {
157
+ descend();
158
+ } else {
159
+ node.visit_nondeferred_class_parts(tw);
160
+ }
157
161
  }
158
162
  if (node instanceof AST_Defun || node instanceof AST_DefClass) {
159
163
  var node_def = node.name.definition();
@@ -217,9 +221,6 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
217
221
  init.walk(tw);
218
222
  });
219
223
  });
220
- self_referential_classes.forEach(function (cls) {
221
- cls.walk(tw);
222
- });
223
224
  // pass 3: we should drop declarations not in_use
224
225
  var tt = new TreeTransformer(
225
226
  function before(node, descend, in_list) {
@@ -231,7 +232,11 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
231
232
  var in_use = in_use_ids.has(def.id);
232
233
  if (node instanceof AST_Assign) {
233
234
  if (!in_use || fixed_ids.has(def.id) && fixed_ids.get(def.id) !== node) {
234
- return maintain_this_binding(parent, node, node.right.transform(tt));
235
+ const assignee = node.right.transform(tt);
236
+ if (!in_use && !assignee.has_side_effects(compressor) && !is_used_in_expression(tt)) {
237
+ return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
238
+ }
239
+ return maintain_this_binding(parent, node, assignee);
235
240
  }
236
241
  } else if (!in_use) {
237
242
  return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
@@ -438,6 +443,14 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
438
443
  scope = save_scope;
439
444
  return node;
440
445
  }
446
+ },
447
+ function after(node, in_list) {
448
+ if (node instanceof AST_Sequence) {
449
+ switch (node.expressions.length) {
450
+ case 0: return in_list ? MAP.skip : make_node(AST_Number, node, { value: 0 });
451
+ case 1: return node.expressions[0];
452
+ }
453
+ }
441
454
  }
442
455
  );
443
456
 
@@ -484,3 +497,41 @@ AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
484
497
  }
485
498
  });
486
499
 
500
+ /**
501
+ * Check if a node may be used by the expression it's in
502
+ * void (0, 1, {node}, 2) -> false
503
+ * console.log(0, {node}) -> true
504
+ */
505
+ function is_used_in_expression(tw) {
506
+ for (let p = -1, node, parent; node = tw.parent(p), parent = tw.parent(p + 1); p++) {
507
+ if (parent instanceof AST_Sequence) {
508
+ const nth_expression = parent.expressions.indexOf(node);
509
+ if (nth_expression !== parent.expressions.length - 1) {
510
+ // Detect (0, x.noThis)() constructs
511
+ const grandparent = tw.parent(p + 2);
512
+ if (
513
+ parent.expressions.length > 2
514
+ || parent.expressions.length === 1
515
+ || !requires_sequence_to_maintain_binding(grandparent, parent, parent.expressions[1])
516
+ ) {
517
+ return false;
518
+ }
519
+ return true;
520
+ } else {
521
+ continue;
522
+ }
523
+ }
524
+ if (parent instanceof AST_Unary) {
525
+ const op = parent.operator;
526
+ if (op === "void") {
527
+ return false;
528
+ }
529
+ if (op === "typeof" || op === "+" || op === "-" || op === "!" || op === "~") {
530
+ continue;
531
+ }
532
+ }
533
+ return true;
534
+ }
535
+
536
+ return true;
537
+ }
package/lib/output.js CHANGED
@@ -1501,7 +1501,9 @@ function OutputStream(options) {
1501
1501
  AST_Arrow.DEFMETHOD("_do_print", function(output) {
1502
1502
  var self = this;
1503
1503
  var parent = output.parent();
1504
- var needs_parens = (parent instanceof AST_Binary && !(parent instanceof AST_Assign)) ||
1504
+ var needs_parens = (parent instanceof AST_Binary &&
1505
+ !(parent instanceof AST_Assign) &&
1506
+ !(parent instanceof AST_DefaultAssign)) ||
1505
1507
  parent instanceof AST_Unary ||
1506
1508
  (parent instanceof AST_Call && self === parent.expression);
1507
1509
  if (needs_parens) { output.print("("); }
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.31.0",
7
+ "version": "5.31.2",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },
package/tools/domprops.js CHANGED
@@ -8225,6 +8225,7 @@ export var domprops = [
8225
8225
  "uint32",
8226
8226
  "uint8",
8227
8227
  "uint8Clamped",
8228
+ "unadjustedMovement",
8228
8229
  "unclippedDepth",
8229
8230
  "unconfigure",
8230
8231
  "undefined",