terser 5.28.0 → 5.28.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 CHANGED
@@ -1,5 +1,9 @@
1
1
  # Changelog
2
2
 
3
+ ## v5.28.1
4
+ (hotfix release)
5
+ - Reverts v5.28.0
6
+
3
7
  ## v5.28.0
4
8
  - Optimise redundant or shrinkable bitwise operations (`|`, `^`, `&`, `>>`, `<<`)
5
9
  - Evaluate some `BigInt` math operations
@@ -12778,8 +12778,8 @@ AST_Class.prototype._size = function () {
12778
12778
  };
12779
12779
 
12780
12780
  AST_ClassStaticBlock.prototype._size = function () {
12781
- // "static{}" + semicolons
12782
- return 8 + list_overhead(this.body);
12781
+ // "class{}" + semicolons
12782
+ return 7 + list_overhead(this.body);
12783
12783
  };
12784
12784
 
12785
12785
  AST_ClassProperty.prototype._size = function () {
@@ -13008,8 +13008,6 @@ function make_node_from_constant(val, orig) {
13008
13008
  operator: "-",
13009
13009
  expression: make_node(AST_Infinity, orig)
13010
13010
  }) : make_node(AST_Infinity, orig);
13011
- case "bigint":
13012
- return make_node(AST_BigInt, orig, { value: val.toString() });
13013
13011
  case "boolean":
13014
13012
  return make_node(val ? AST_True : AST_False, orig);
13015
13013
  case "undefined":
@@ -13488,7 +13486,6 @@ const is_pure_native_value = make_nested_lookup({
13488
13486
  const is_undeclared_ref = (node) =>
13489
13487
  node instanceof AST_SymbolRef && node.definition().undeclared;
13490
13488
 
13491
- const bitwise_binop = makePredicate("<<< >> << & | ^ ~");
13492
13489
  const lazy_op = makePredicate("&& || ??");
13493
13490
  const unary_side_effects = makePredicate("delete ++ --");
13494
13491
 
@@ -13549,24 +13546,6 @@ const unary_side_effects = makePredicate("delete ++ --");
13549
13546
  node.DEFMETHOD("is_number", func);
13550
13547
  });
13551
13548
 
13552
- // methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size
13553
- (function(def_is_32_bit_integer) {
13554
- def_is_32_bit_integer(AST_Node, return_false);
13555
- def_is_32_bit_integer(AST_Number, function() {
13556
- return this.value === (this.value | 0);
13557
- });
13558
- def_is_32_bit_integer(AST_UnaryPrefix, function() {
13559
- return this.operator == "~" ? this.expression.is_number()
13560
- : this.operator === "+" ? this.expression.is_32_bit_integer()
13561
- : false;
13562
- });
13563
- def_is_32_bit_integer(AST_Binary, function() {
13564
- return bitwise_binop.has(this.operator);
13565
- });
13566
- }(function (node, func) {
13567
- node.DEFMETHOD("is_32_bit_integer", func);
13568
- }));
13569
-
13570
13549
  // methods to determine if an expression has a string result type
13571
13550
  (function(def_is_string) {
13572
13551
  def_is_string(AST_Node, return_false);
@@ -14181,37 +14160,6 @@ function is_lhs(node, parent) {
14181
14160
  });
14182
14161
  });
14183
14162
 
14184
- (function (def_bitwise_negate) {
14185
- function basic_negation(exp) {
14186
- return make_node(AST_UnaryPrefix, exp, {
14187
- operator: "~",
14188
- expression: exp
14189
- });
14190
- }
14191
-
14192
- def_bitwise_negate(AST_Node, function() {
14193
- return basic_negation(this);
14194
- });
14195
-
14196
- def_bitwise_negate(AST_Number, function() {
14197
- const neg = ~this.value;
14198
- if (neg.toString().length > this.value.toString().length) {
14199
- return basic_negation(this);
14200
- }
14201
- return make_node(AST_Number, this, { value: neg });
14202
- });
14203
-
14204
- def_bitwise_negate(AST_UnaryPrefix, function(in_32_bit_context) {
14205
- if (this.operator == "~" && (in_32_bit_context || this.expression.is_32_bit_integer())) {
14206
- return this.expression;
14207
- } else {
14208
- return basic_negation(this);
14209
- }
14210
- });
14211
- })(function (node, func) {
14212
- node.DEFMETHOD("bitwise_negate", func);
14213
- });
14214
-
14215
14163
  // Is the callee of this function pure?
14216
14164
  var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError");
14217
14165
  AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
@@ -14437,14 +14385,7 @@ def_eval(AST_Constant, function () {
14437
14385
  return this.getValue();
14438
14386
  });
14439
14387
 
14440
- const supports_bigint = typeof BigInt === "function";
14441
- def_eval(AST_BigInt, function () {
14442
- if (supports_bigint) {
14443
- return BigInt(this.value);
14444
- } else {
14445
- return this;
14446
- }
14447
- });
14388
+ def_eval(AST_BigInt, return_this);
14448
14389
 
14449
14390
  def_eval(AST_RegExp, function (compressor) {
14450
14391
  let evaluated = compressor.evaluated_regexps.get(this.value);
@@ -14568,6 +14509,7 @@ def_eval(AST_Binary, function (compressor, depth) {
14568
14509
  var right = this.right._eval(compressor, depth);
14569
14510
  if (right === this.right)
14570
14511
  return this;
14512
+ var result;
14571
14513
 
14572
14514
  if (left != null
14573
14515
  && right != null
@@ -14579,17 +14521,6 @@ def_eval(AST_Binary, function (compressor, depth) {
14579
14521
  return this;
14580
14522
  }
14581
14523
 
14582
- // Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n`
14583
- if (
14584
- (typeof left === "bigint") !== (typeof right === "bigint")
14585
- || typeof left === "bigint"
14586
- && (this.operator === ">>>"
14587
- || this.operator === "/" && Number(right) === 0)
14588
- ) {
14589
- return this;
14590
- }
14591
-
14592
- var result;
14593
14524
  switch (this.operator) {
14594
14525
  case "&&": result = left && right; break;
14595
14526
  case "||": result = left || right; break;
@@ -14599,7 +14530,7 @@ def_eval(AST_Binary, function (compressor, depth) {
14599
14530
  case "^": result = left ^ right; break;
14600
14531
  case "+": result = left + right; break;
14601
14532
  case "*": result = left * right; break;
14602
- case "**": result = left ** right; break;
14533
+ case "**": result = Math.pow(left, right); break;
14603
14534
  case "/": result = left / right; break;
14604
14535
  case "%": result = left % right; break;
14605
14536
  case "-": result = left - right; break;
@@ -14617,7 +14548,7 @@ def_eval(AST_Binary, function (compressor, depth) {
14617
14548
  default:
14618
14549
  return this;
14619
14550
  }
14620
- if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) {
14551
+ if (isNaN(result) && compressor.find_parent(AST_With)) {
14621
14552
  // leave original expression as is
14622
14553
  return this;
14623
14554
  }
@@ -18615,33 +18546,6 @@ class Compressor extends TreeWalker {
18615
18546
  }
18616
18547
  }
18617
18548
 
18618
- in_32_bit_context() {
18619
- if (!this.option("evaluate")) return false;
18620
- var self = this.self();
18621
- for (var i = 0, p; p = this.parent(i); i++) {
18622
- if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) {
18623
- return true;
18624
- }
18625
- if (p instanceof AST_UnaryPrefix) {
18626
- return p.operator === "~";
18627
- }
18628
- if (
18629
- p instanceof AST_Binary
18630
- && (
18631
- p.operator == "&&"
18632
- || p.operator == "||"
18633
- || p.operator == "??"
18634
- )
18635
- || p instanceof AST_Conditional && p.condition !== self
18636
- || p.tail_node() === self
18637
- ) {
18638
- self = p;
18639
- } else {
18640
- return false;
18641
- }
18642
- }
18643
- }
18644
-
18645
18549
  get_toplevel() {
18646
18550
  return this._toplevel;
18647
18551
  }
@@ -20340,40 +20244,9 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) {
20340
20244
  right: e.right
20341
20245
  });
20342
20246
  }
20343
-
20344
- if (compressor.option("evaluate")) {
20345
- // ~~x => x (in 32-bit context)
20346
- // ~~{32 bit integer} => {32 bit integer}
20347
- if (
20348
- self.operator === "~"
20349
- && self.expression instanceof AST_UnaryPrefix
20350
- && self.expression.operator === "~"
20351
- && (compressor.in_32_bit_context() || self.expression.expression.is_32_bit_integer())
20352
- ) {
20353
- return self.expression.expression;
20354
- }
20355
-
20356
- // ~(x ^ y) => x ^ ~y
20357
- if (
20358
- self.operator === "~"
20359
- && e instanceof AST_Binary
20360
- && e.operator === "^"
20361
- ) {
20362
- if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") {
20363
- // ~(~x ^ y) => x ^ y
20364
- e.left = e.left.bitwise_negate(true);
20365
- } else {
20366
- e.right = e.right.bitwise_negate(true);
20367
- }
20368
- return e;
20369
- }
20370
- }
20371
-
20372
- if (
20373
- self.operator != "-"
20374
- // avoid infinite recursion of numerals
20375
- || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)
20376
- ) {
20247
+ // avoids infinite recursion of numerals
20248
+ if (self.operator != "-"
20249
+ || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)) {
20377
20250
  var ev = self.evaluate(compressor);
20378
20251
  if (ev !== self) {
20379
20252
  ev = make_node_from_constant(ev, self).optimize(compressor);
@@ -20464,7 +20337,6 @@ def_optimize(AST_Binary, function(self, compressor) {
20464
20337
  self.left.equivalent_to(self.right)) {
20465
20338
  self.operator = self.operator.substr(0, 2);
20466
20339
  }
20467
-
20468
20340
  // XXX: intentionally falling down to the next case
20469
20341
  case "==":
20470
20342
  case "!=":
@@ -20506,55 +20378,6 @@ def_optimize(AST_Binary, function(self, compressor) {
20506
20378
  && self.left.definition() === self.right.definition()
20507
20379
  && is_object(self.left.fixed_value())) {
20508
20380
  return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
20509
- } else if (self.left.is_32_bit_integer() && self.right.is_32_bit_integer()) {
20510
- const not = node => make_node(AST_UnaryPrefix, node, {
20511
- operator: "!",
20512
- expression: node
20513
- });
20514
- const booleanify = (node, truthy) => {
20515
- if (truthy) {
20516
- return compressor.in_boolean_context()
20517
- ? node
20518
- : not(not(node));
20519
- } else {
20520
- return not(node);
20521
- }
20522
- };
20523
-
20524
- // The only falsy 32-bit integer is 0
20525
- if (self.left instanceof AST_Number && self.left.value === 0) {
20526
- return booleanify(self.right, self.operator[0] === "!");
20527
- }
20528
- if (self.right instanceof AST_Number && self.right.value === 0) {
20529
- return booleanify(self.left, self.operator[0] === "!");
20530
- }
20531
-
20532
- // Mask all-bits check
20533
- // (x & 0xFF) != 0xFF => !(~x & 0xFF)
20534
- let and_op, x, mask;
20535
- if (
20536
- (and_op =
20537
- self.left instanceof AST_Binary ? self.left
20538
- : self.right instanceof AST_Binary ? self.right : null)
20539
- && (mask = and_op === self.left ? self.right : self.left)
20540
- && and_op.operator === "&"
20541
- && mask instanceof AST_Number
20542
- && mask.is_32_bit_integer()
20543
- && (x =
20544
- and_op.left.equivalent_to(mask) ? and_op.right
20545
- : and_op.right.equivalent_to(mask) ? and_op.left : null)
20546
- ) {
20547
- let optimized = booleanify(make_node(AST_Binary, self, {
20548
- operator: "&",
20549
- left: mask,
20550
- right: make_node(AST_UnaryPrefix, self, {
20551
- operator: "~",
20552
- expression: x
20553
- })
20554
- }), self.operator[0] === "=");
20555
-
20556
- return best_of(compressor, optimized, self);
20557
- }
20558
20381
  }
20559
20382
  break;
20560
20383
  case "&&":
@@ -20928,157 +20751,6 @@ def_optimize(AST_Binary, function(self, compressor) {
20928
20751
  }
20929
20752
  }
20930
20753
  }
20931
-
20932
- // bitwise ops
20933
- if (bitwise_binop.has(self.operator)) {
20934
- // Use De Morgan's laws
20935
- // z & (X | y)
20936
- // => z & X (given y & z === 0)
20937
- // => z & X | {y & z} (given y & z !== 0)
20938
- let y, z, x_node, y_node, z_node = self.left;
20939
- if (
20940
- self.operator === "&"
20941
- && self.right instanceof AST_Binary
20942
- && self.right.operator === "|"
20943
- && typeof (z = self.left.evaluate(compressor)) === "number"
20944
- ) {
20945
- if (typeof (y = self.right.right.evaluate(compressor)) === "number") {
20946
- // z & (X | y)
20947
- x_node = self.right.left;
20948
- y_node = self.right.right;
20949
- } else if (typeof (y = self.right.left.evaluate(compressor)) === "number") {
20950
- // z & (y | X)
20951
- x_node = self.right.right;
20952
- y_node = self.right.left;
20953
- }
20954
-
20955
- if ((y & z) === 0) {
20956
- self = make_node(AST_Binary, self, {
20957
- operator: self.operator,
20958
- left: z_node,
20959
- right: x_node
20960
- });
20961
- } else {
20962
- const reordered_ops = make_node(AST_Binary, self, {
20963
- operator: "|",
20964
- left: make_node(AST_Binary, self, {
20965
- operator: "&",
20966
- left: x_node,
20967
- right: z_node
20968
- }),
20969
- right: make_node_from_constant(y & z, y_node),
20970
- });
20971
-
20972
- self = best_of(compressor, self, reordered_ops);
20973
- }
20974
- }
20975
-
20976
- // x ^ x => 0
20977
- // x | x => 0 | x
20978
- // x & x => 0 | x
20979
- const same_operands = self.left.equivalent_to(self.right) && !self.left.has_side_effects(compressor);
20980
- if (same_operands) {
20981
- if (self.operator === "^") {
20982
- return make_node(AST_Number, self, { value: 0 });
20983
- }
20984
- if (self.operator === "|" || self.operator === "&") {
20985
- self.left = make_node(AST_Number, self, { value: 0 });
20986
- self.operator = "|";
20987
- }
20988
- }
20989
-
20990
-
20991
- // Shifts that do nothing
20992
- // {anything} >> 0 => {anything} | 0
20993
- // {anything} << 0 => {anything} | 0
20994
- if (
20995
- (self.operator === "<<" || self.operator === ">>")
20996
- && self.right instanceof AST_Number && self.right.value === 0
20997
- ) {
20998
- self.operator = "|";
20999
- }
21000
-
21001
- // Find useless to-bitwise conversions
21002
- // {32 bit integer} | 0 => {32 bit integer}
21003
- // {32 bit integer} ^ 0 => {32 bit integer}
21004
- const zero_side = self.right instanceof AST_Number && self.right.value === 0 ? self.right
21005
- : self.left instanceof AST_Number && self.left.value === 0 ? self.left
21006
- : null;
21007
- const non_zero_side = zero_side && (zero_side === self.right ? self.left : self.right);
21008
- if (
21009
- zero_side
21010
- && (self.operator === "|" || self.operator === "^")
21011
- && (non_zero_side.is_32_bit_integer() || compressor.in_32_bit_context())
21012
- ) {
21013
- return non_zero_side;
21014
- }
21015
-
21016
- // {anything} & 0 => 0
21017
- if (
21018
- zero_side
21019
- && self.operator === "&"
21020
- && !non_zero_side.has_side_effects(compressor)
21021
- ) {
21022
- return zero_side;
21023
- }
21024
-
21025
- const is_full_mask = (node) =>
21026
- node instanceof AST_Number && node.value === -1
21027
- ||
21028
- node instanceof AST_UnaryPrefix && (
21029
- node.operator === "-"
21030
- && node.expression instanceof AST_Number
21031
- && node.expression.value === 1
21032
- || node.operator === "~"
21033
- && node.expression instanceof AST_Number
21034
- && node.expression.value === 0);
21035
-
21036
- const full_mask = is_full_mask(self.right) ? self.right
21037
- : is_full_mask(self.left) ? self.left
21038
- : null;
21039
- const non_full_mask_side = full_mask && (full_mask === self.right ? self.left : self.right);
21040
-
21041
- switch (self.operator) {
21042
- case "|":
21043
- // {anything} | -1 => -1
21044
- if (full_mask && !non_full_mask_side.has_side_effects(compressor)) {
21045
- return full_mask;
21046
- }
21047
-
21048
- break;
21049
- case "&":
21050
- // {32 bit integer} & -1 => {32 bit integer}
21051
- if (
21052
- full_mask
21053
- && (non_full_mask_side.is_32_bit_integer() || compressor.in_32_bit_context())
21054
- ) {
21055
- return non_full_mask_side;
21056
- }
21057
-
21058
- break;
21059
- case "^":
21060
- // {anything} ^ -1 => ~{anything}
21061
- if (full_mask) {
21062
- return non_full_mask_side.bitwise_negate(compressor.in_32_bit_context());
21063
- }
21064
-
21065
- // ~x ^ ~y => x ^ y
21066
- if (
21067
- self.left instanceof AST_UnaryPrefix
21068
- && self.left.operator === "~"
21069
- && self.right instanceof AST_UnaryPrefix
21070
- && self.right.operator === "~"
21071
- ) {
21072
- self = make_node(AST_Binary, self, {
21073
- operator: "^",
21074
- left: self.left.expression,
21075
- right: self.right.expression
21076
- });
21077
- }
21078
-
21079
- break;
21080
- }
21081
- }
21082
20754
  }
21083
20755
  // x && (y && z) ==> x && y && z
21084
20756
  // x || (y || z) ==> x || y || z
@@ -44,7 +44,6 @@
44
44
  import {
45
45
  AST_Array,
46
46
  AST_Arrow,
47
- AST_BigInt,
48
47
  AST_BlockStatement,
49
48
  AST_Call,
50
49
  AST_Chain,
@@ -125,8 +124,6 @@ export function make_node_from_constant(val, orig) {
125
124
  operator: "-",
126
125
  expression: make_node(AST_Infinity, orig)
127
126
  }) : make_node(AST_Infinity, orig);
128
- case "bigint":
129
- return make_node(AST_BigInt, orig, { value: val.toString() });
130
127
  case "boolean":
131
128
  return make_node(val ? AST_True : AST_False, orig);
132
129
  case "undefined":
@@ -133,14 +133,7 @@ def_eval(AST_Constant, function () {
133
133
  return this.getValue();
134
134
  });
135
135
 
136
- const supports_bigint = typeof BigInt === "function";
137
- def_eval(AST_BigInt, function () {
138
- if (supports_bigint) {
139
- return BigInt(this.value);
140
- } else {
141
- return this;
142
- }
143
- });
136
+ def_eval(AST_BigInt, return_this);
144
137
 
145
138
  def_eval(AST_RegExp, function (compressor) {
146
139
  let evaluated = compressor.evaluated_regexps.get(this.value);
@@ -264,6 +257,7 @@ def_eval(AST_Binary, function (compressor, depth) {
264
257
  var right = this.right._eval(compressor, depth);
265
258
  if (right === this.right)
266
259
  return this;
260
+ var result;
267
261
 
268
262
  if (left != null
269
263
  && right != null
@@ -275,17 +269,6 @@ def_eval(AST_Binary, function (compressor, depth) {
275
269
  return this;
276
270
  }
277
271
 
278
- // Do not mix BigInt and Number; Don't use `>>>` on BigInt or `/ 0n`
279
- if (
280
- (typeof left === "bigint") !== (typeof right === "bigint")
281
- || typeof left === "bigint"
282
- && (this.operator === ">>>"
283
- || this.operator === "/" && Number(right) === 0)
284
- ) {
285
- return this;
286
- }
287
-
288
- var result;
289
272
  switch (this.operator) {
290
273
  case "&&": result = left && right; break;
291
274
  case "||": result = left || right; break;
@@ -295,7 +278,7 @@ def_eval(AST_Binary, function (compressor, depth) {
295
278
  case "^": result = left ^ right; break;
296
279
  case "+": result = left + right; break;
297
280
  case "*": result = left * right; break;
298
- case "**": result = left ** right; break;
281
+ case "**": result = Math.pow(left, right); break;
299
282
  case "/": result = left / right; break;
300
283
  case "%": result = left % right; break;
301
284
  case "-": result = left - right; break;
@@ -313,7 +296,7 @@ def_eval(AST_Binary, function (compressor, depth) {
313
296
  default:
314
297
  return this;
315
298
  }
316
- if (typeof result === "number" && isNaN(result) && compressor.find_parent(AST_With)) {
299
+ if (isNaN(result) && compressor.find_parent(AST_With)) {
317
300
  // leave original expression as is
318
301
  return this;
319
302
  }
@@ -170,7 +170,6 @@ import "./drop-unused.js";
170
170
  import "./reduce-vars.js";
171
171
  import {
172
172
  is_undeclared_ref,
173
- bitwise_binop,
174
173
  lazy_op,
175
174
  is_nullish,
176
175
  is_undefined,
@@ -374,33 +373,6 @@ class Compressor extends TreeWalker {
374
373
  }
375
374
  }
376
375
 
377
- in_32_bit_context() {
378
- if (!this.option("evaluate")) return false;
379
- var self = this.self();
380
- for (var i = 0, p; p = this.parent(i); i++) {
381
- if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) {
382
- return true;
383
- }
384
- if (p instanceof AST_UnaryPrefix) {
385
- return p.operator === "~";
386
- }
387
- if (
388
- p instanceof AST_Binary
389
- && (
390
- p.operator == "&&"
391
- || p.operator == "||"
392
- || p.operator == "??"
393
- )
394
- || p instanceof AST_Conditional && p.condition !== self
395
- || p.tail_node() === self
396
- ) {
397
- self = p;
398
- } else {
399
- return false;
400
- }
401
- }
402
- }
403
-
404
376
  get_toplevel() {
405
377
  return this._toplevel;
406
378
  }
@@ -2099,40 +2071,9 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) {
2099
2071
  right: e.right
2100
2072
  });
2101
2073
  }
2102
-
2103
- if (compressor.option("evaluate")) {
2104
- // ~~x => x (in 32-bit context)
2105
- // ~~{32 bit integer} => {32 bit integer}
2106
- if (
2107
- self.operator === "~"
2108
- && self.expression instanceof AST_UnaryPrefix
2109
- && self.expression.operator === "~"
2110
- && (compressor.in_32_bit_context() || self.expression.expression.is_32_bit_integer())
2111
- ) {
2112
- return self.expression.expression;
2113
- }
2114
-
2115
- // ~(x ^ y) => x ^ ~y
2116
- if (
2117
- self.operator === "~"
2118
- && e instanceof AST_Binary
2119
- && e.operator === "^"
2120
- ) {
2121
- if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") {
2122
- // ~(~x ^ y) => x ^ y
2123
- e.left = e.left.bitwise_negate(true);
2124
- } else {
2125
- e.right = e.right.bitwise_negate(true);
2126
- }
2127
- return e;
2128
- }
2129
- }
2130
-
2131
- if (
2132
- self.operator != "-"
2133
- // avoid infinite recursion of numerals
2134
- || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)
2135
- ) {
2074
+ // avoids infinite recursion of numerals
2075
+ if (self.operator != "-"
2076
+ || !(e instanceof AST_Number || e instanceof AST_Infinity || e instanceof AST_BigInt)) {
2136
2077
  var ev = self.evaluate(compressor);
2137
2078
  if (ev !== self) {
2138
2079
  ev = make_node_from_constant(ev, self).optimize(compressor);
@@ -2223,7 +2164,6 @@ def_optimize(AST_Binary, function(self, compressor) {
2223
2164
  self.left.equivalent_to(self.right)) {
2224
2165
  self.operator = self.operator.substr(0, 2);
2225
2166
  }
2226
-
2227
2167
  // XXX: intentionally falling down to the next case
2228
2168
  case "==":
2229
2169
  case "!=":
@@ -2265,55 +2205,6 @@ def_optimize(AST_Binary, function(self, compressor) {
2265
2205
  && self.left.definition() === self.right.definition()
2266
2206
  && is_object(self.left.fixed_value())) {
2267
2207
  return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
2268
- } else if (self.left.is_32_bit_integer() && self.right.is_32_bit_integer()) {
2269
- const not = node => make_node(AST_UnaryPrefix, node, {
2270
- operator: "!",
2271
- expression: node
2272
- });
2273
- const booleanify = (node, truthy) => {
2274
- if (truthy) {
2275
- return compressor.in_boolean_context()
2276
- ? node
2277
- : not(not(node));
2278
- } else {
2279
- return not(node);
2280
- }
2281
- };
2282
-
2283
- // The only falsy 32-bit integer is 0
2284
- if (self.left instanceof AST_Number && self.left.value === 0) {
2285
- return booleanify(self.right, self.operator[0] === "!");
2286
- }
2287
- if (self.right instanceof AST_Number && self.right.value === 0) {
2288
- return booleanify(self.left, self.operator[0] === "!");
2289
- }
2290
-
2291
- // Mask all-bits check
2292
- // (x & 0xFF) != 0xFF => !(~x & 0xFF)
2293
- let and_op, x, mask;
2294
- if (
2295
- (and_op =
2296
- self.left instanceof AST_Binary ? self.left
2297
- : self.right instanceof AST_Binary ? self.right : null)
2298
- && (mask = and_op === self.left ? self.right : self.left)
2299
- && and_op.operator === "&"
2300
- && mask instanceof AST_Number
2301
- && mask.is_32_bit_integer()
2302
- && (x =
2303
- and_op.left.equivalent_to(mask) ? and_op.right
2304
- : and_op.right.equivalent_to(mask) ? and_op.left : null)
2305
- ) {
2306
- let optimized = booleanify(make_node(AST_Binary, self, {
2307
- operator: "&",
2308
- left: mask,
2309
- right: make_node(AST_UnaryPrefix, self, {
2310
- operator: "~",
2311
- expression: x
2312
- })
2313
- }), self.operator[0] === "=");
2314
-
2315
- return best_of(compressor, optimized, self);
2316
- }
2317
2208
  }
2318
2209
  break;
2319
2210
  case "&&":
@@ -2687,157 +2578,6 @@ def_optimize(AST_Binary, function(self, compressor) {
2687
2578
  }
2688
2579
  }
2689
2580
  }
2690
-
2691
- // bitwise ops
2692
- if (bitwise_binop.has(self.operator)) {
2693
- // Use De Morgan's laws
2694
- // z & (X | y)
2695
- // => z & X (given y & z === 0)
2696
- // => z & X | {y & z} (given y & z !== 0)
2697
- let y, z, x_node, y_node, z_node = self.left;
2698
- if (
2699
- self.operator === "&"
2700
- && self.right instanceof AST_Binary
2701
- && self.right.operator === "|"
2702
- && typeof (z = self.left.evaluate(compressor)) === "number"
2703
- ) {
2704
- if (typeof (y = self.right.right.evaluate(compressor)) === "number") {
2705
- // z & (X | y)
2706
- x_node = self.right.left;
2707
- y_node = self.right.right;
2708
- } else if (typeof (y = self.right.left.evaluate(compressor)) === "number") {
2709
- // z & (y | X)
2710
- x_node = self.right.right;
2711
- y_node = self.right.left;
2712
- }
2713
-
2714
- if ((y & z) === 0) {
2715
- self = make_node(AST_Binary, self, {
2716
- operator: self.operator,
2717
- left: z_node,
2718
- right: x_node
2719
- });
2720
- } else {
2721
- const reordered_ops = make_node(AST_Binary, self, {
2722
- operator: "|",
2723
- left: make_node(AST_Binary, self, {
2724
- operator: "&",
2725
- left: x_node,
2726
- right: z_node
2727
- }),
2728
- right: make_node_from_constant(y & z, y_node),
2729
- });
2730
-
2731
- self = best_of(compressor, self, reordered_ops);
2732
- }
2733
- }
2734
-
2735
- // x ^ x => 0
2736
- // x | x => 0 | x
2737
- // x & x => 0 | x
2738
- const same_operands = self.left.equivalent_to(self.right) && !self.left.has_side_effects(compressor);
2739
- if (same_operands) {
2740
- if (self.operator === "^") {
2741
- return make_node(AST_Number, self, { value: 0 });
2742
- }
2743
- if (self.operator === "|" || self.operator === "&") {
2744
- self.left = make_node(AST_Number, self, { value: 0 });
2745
- self.operator = "|";
2746
- }
2747
- }
2748
-
2749
-
2750
- // Shifts that do nothing
2751
- // {anything} >> 0 => {anything} | 0
2752
- // {anything} << 0 => {anything} | 0
2753
- if (
2754
- (self.operator === "<<" || self.operator === ">>")
2755
- && self.right instanceof AST_Number && self.right.value === 0
2756
- ) {
2757
- self.operator = "|";
2758
- }
2759
-
2760
- // Find useless to-bitwise conversions
2761
- // {32 bit integer} | 0 => {32 bit integer}
2762
- // {32 bit integer} ^ 0 => {32 bit integer}
2763
- const zero_side = self.right instanceof AST_Number && self.right.value === 0 ? self.right
2764
- : self.left instanceof AST_Number && self.left.value === 0 ? self.left
2765
- : null;
2766
- const non_zero_side = zero_side && (zero_side === self.right ? self.left : self.right);
2767
- if (
2768
- zero_side
2769
- && (self.operator === "|" || self.operator === "^")
2770
- && (non_zero_side.is_32_bit_integer() || compressor.in_32_bit_context())
2771
- ) {
2772
- return non_zero_side;
2773
- }
2774
-
2775
- // {anything} & 0 => 0
2776
- if (
2777
- zero_side
2778
- && self.operator === "&"
2779
- && !non_zero_side.has_side_effects(compressor)
2780
- ) {
2781
- return zero_side;
2782
- }
2783
-
2784
- const is_full_mask = (node) =>
2785
- node instanceof AST_Number && node.value === -1
2786
- ||
2787
- node instanceof AST_UnaryPrefix && (
2788
- node.operator === "-"
2789
- && node.expression instanceof AST_Number
2790
- && node.expression.value === 1
2791
- || node.operator === "~"
2792
- && node.expression instanceof AST_Number
2793
- && node.expression.value === 0);
2794
-
2795
- const full_mask = is_full_mask(self.right) ? self.right
2796
- : is_full_mask(self.left) ? self.left
2797
- : null;
2798
- const non_full_mask_side = full_mask && (full_mask === self.right ? self.left : self.right);
2799
-
2800
- switch (self.operator) {
2801
- case "|":
2802
- // {anything} | -1 => -1
2803
- if (full_mask && !non_full_mask_side.has_side_effects(compressor)) {
2804
- return full_mask;
2805
- }
2806
-
2807
- break;
2808
- case "&":
2809
- // {32 bit integer} & -1 => {32 bit integer}
2810
- if (
2811
- full_mask
2812
- && (non_full_mask_side.is_32_bit_integer() || compressor.in_32_bit_context())
2813
- ) {
2814
- return non_full_mask_side;
2815
- }
2816
-
2817
- break;
2818
- case "^":
2819
- // {anything} ^ -1 => ~{anything}
2820
- if (full_mask) {
2821
- return non_full_mask_side.bitwise_negate(compressor.in_32_bit_context());
2822
- }
2823
-
2824
- // ~x ^ ~y => x ^ y
2825
- if (
2826
- self.left instanceof AST_UnaryPrefix
2827
- && self.left.operator === "~"
2828
- && self.right instanceof AST_UnaryPrefix
2829
- && self.right.operator === "~"
2830
- ) {
2831
- self = make_node(AST_Binary, self, {
2832
- operator: "^",
2833
- left: self.left.expression,
2834
- right: self.right.expression
2835
- });
2836
- }
2837
-
2838
- break;
2839
- }
2840
- }
2841
2581
  }
2842
2582
  // x && (y && z) ==> x && y && z
2843
2583
  // x || (y || z) ==> x || y || z
@@ -133,7 +133,6 @@ import { pure_prop_access_globals, is_pure_native_fn, is_pure_native_method } fr
133
133
  export const is_undeclared_ref = (node) =>
134
134
  node instanceof AST_SymbolRef && node.definition().undeclared;
135
135
 
136
- export const bitwise_binop = makePredicate("<<< >> << & | ^ ~");
137
136
  export const lazy_op = makePredicate("&& || ??");
138
137
  export const unary_side_effects = makePredicate("delete ++ --");
139
138
 
@@ -194,24 +193,6 @@ export const unary_side_effects = makePredicate("delete ++ --");
194
193
  node.DEFMETHOD("is_number", func);
195
194
  });
196
195
 
197
- // methods to determine if an expression is a 32 bit integer (IE results from bitwise ops, or is an integer constant fitting in that size
198
- (function(def_is_32_bit_integer) {
199
- def_is_32_bit_integer(AST_Node, return_false);
200
- def_is_32_bit_integer(AST_Number, function() {
201
- return this.value === (this.value | 0);
202
- });
203
- def_is_32_bit_integer(AST_UnaryPrefix, function() {
204
- return this.operator == "~" ? this.expression.is_number()
205
- : this.operator === "+" ? this.expression.is_32_bit_integer()
206
- : false;
207
- });
208
- def_is_32_bit_integer(AST_Binary, function() {
209
- return bitwise_binop.has(this.operator);
210
- });
211
- }(function (node, func) {
212
- node.DEFMETHOD("is_32_bit_integer", func);
213
- }));
214
-
215
196
  // methods to determine if an expression has a string result type
216
197
  (function(def_is_string) {
217
198
  def_is_string(AST_Node, return_false);
@@ -826,37 +807,6 @@ export function is_lhs(node, parent) {
826
807
  });
827
808
  });
828
809
 
829
- (function (def_bitwise_negate) {
830
- function basic_negation(exp) {
831
- return make_node(AST_UnaryPrefix, exp, {
832
- operator: "~",
833
- expression: exp
834
- });
835
- }
836
-
837
- def_bitwise_negate(AST_Node, function() {
838
- return basic_negation(this);
839
- });
840
-
841
- def_bitwise_negate(AST_Number, function() {
842
- const neg = ~this.value;
843
- if (neg.toString().length > this.value.toString().length) {
844
- return basic_negation(this);
845
- }
846
- return make_node(AST_Number, this, { value: neg });
847
- });
848
-
849
- def_bitwise_negate(AST_UnaryPrefix, function(in_32_bit_context) {
850
- if (this.operator == "~" && (in_32_bit_context || this.expression.is_32_bit_integer())) {
851
- return this.expression;
852
- } else {
853
- return basic_negation(this);
854
- }
855
- });
856
- })(function (node, func) {
857
- node.DEFMETHOD("bitwise_negate", func);
858
- });
859
-
860
810
  // Is the callee of this function pure?
861
811
  var global_pure_fns = makePredicate("Boolean decodeURI decodeURIComponent Date encodeURI encodeURIComponent Error escape EvalError isFinite isNaN Number Object parseFloat parseInt RangeError ReferenceError String SyntaxError TypeError unescape URIError");
862
812
  AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
package/lib/size.js CHANGED
@@ -406,8 +406,8 @@ AST_Class.prototype._size = function () {
406
406
  };
407
407
 
408
408
  AST_ClassStaticBlock.prototype._size = function () {
409
- // "static{}" + semicolons
410
- return 8 + list_overhead(this.body);
409
+ // "class{}" + semicolons
410
+ return 7 + list_overhead(this.body);
411
411
  };
412
412
 
413
413
  AST_ClassProperty.prototype._size = function () {
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.28.0",
7
+ "version": "5.28.1",
8
8
  "engines": {
9
9
  "node": ">=10"
10
10
  },