terser 5.39.0 → 5.39.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 +4 -0
- package/README.md +2 -1
- package/dist/bundle.min.js +173 -93
- package/lib/compress/index.js +76 -72
- package/lib/compress/inference.js +97 -21
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
@@ -871,7 +871,8 @@ If you happen to need the source map as a raw object, set `sourceMap.asObject` t
|
|
871
871
|
allow improved compression. This might be unsafe when an at least one of two
|
872
872
|
operands is an object with computed values due the use of methods like `get`,
|
873
873
|
or `valueOf`. This could cause change in execution order after operands in the
|
874
|
-
comparison are switching.
|
874
|
+
comparison are switching. Or if one of two operands is `NaN`, the result is always
|
875
|
+
`false`. Compression only works if both `comparisons` and
|
875
876
|
`unsafe_comps` are both set to true.
|
876
877
|
|
877
878
|
- `unsafe_Function` (default: `false`) -- compress and mangle `Function(args, code)`
|
package/dist/bundle.min.js
CHANGED
@@ -13676,18 +13676,24 @@ const unary_side_effects = makePredicate("delete ++ --");
|
|
13676
13676
|
def_is_number(AST_Node, return_false);
|
13677
13677
|
def_is_number(AST_Number, return_true);
|
13678
13678
|
const unary = makePredicate("+ - ~ ++ --");
|
13679
|
-
def_is_number(AST_Unary, function() {
|
13680
|
-
return unary.has(this.operator) &&
|
13679
|
+
def_is_number(AST_Unary, function(compressor) {
|
13680
|
+
return unary.has(this.operator) && this.expression.is_number(compressor);
|
13681
13681
|
});
|
13682
13682
|
const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
|
13683
13683
|
def_is_number(AST_Binary, function(compressor) {
|
13684
|
-
|
13685
|
-
|
13686
|
-
&& this.right.
|
13684
|
+
if (this.operator === "+") {
|
13685
|
+
// Both sides need to be `number`. Or one is a `number` and the other is number-ish.
|
13686
|
+
return this.left.is_number(compressor) && this.right.is_number_or_bigint(compressor)
|
13687
|
+
|| this.right.is_number(compressor) && this.left.is_number_or_bigint(compressor);
|
13688
|
+
} else if (numeric_ops.has(this.operator)) {
|
13689
|
+
return this.left.is_number(compressor) || this.right.is_number(compressor);
|
13690
|
+
} else {
|
13691
|
+
return false;
|
13692
|
+
}
|
13687
13693
|
});
|
13688
13694
|
def_is_number(AST_Assign, function(compressor) {
|
13689
|
-
return numeric_ops.has(this.operator.slice(0, -1))
|
13690
|
-
|
13695
|
+
return (this.operator === "=" || numeric_ops.has(this.operator.slice(0, -1)))
|
13696
|
+
&& this.right.is_number(compressor);
|
13691
13697
|
});
|
13692
13698
|
def_is_number(AST_Sequence, function(compressor) {
|
13693
13699
|
return this.tail_node().is_number(compressor);
|
@@ -13699,19 +13705,83 @@ const unary_side_effects = makePredicate("delete ++ --");
|
|
13699
13705
|
node.DEFMETHOD("is_number", func);
|
13700
13706
|
});
|
13701
13707
|
|
13708
|
+
// methods to determine if an expression returns a BigInt
|
13709
|
+
(function(def_is_bigint) {
|
13710
|
+
def_is_bigint(AST_Node, return_false);
|
13711
|
+
def_is_bigint(AST_BigInt, return_true);
|
13712
|
+
const unary = makePredicate("+ - ~ ++ --");
|
13713
|
+
def_is_bigint(AST_Unary, function(compressor) {
|
13714
|
+
return unary.has(this.operator) && this.expression.is_bigint(compressor);
|
13715
|
+
});
|
13716
|
+
const numeric_ops = makePredicate("- * / % & | ^ << >>");
|
13717
|
+
def_is_bigint(AST_Binary, function(compressor) {
|
13718
|
+
if (this.operator === "+") {
|
13719
|
+
return this.left.is_bigint(compressor) && this.right.is_number_or_bigint(compressor)
|
13720
|
+
|| this.right.is_bigint(compressor) && this.left.is_number_or_bigint(compressor);
|
13721
|
+
} else if (numeric_ops.has(this.operator)) {
|
13722
|
+
return this.left.is_bigint(compressor) || this.right.is_bigint(compressor);
|
13723
|
+
} else {
|
13724
|
+
return false;
|
13725
|
+
}
|
13726
|
+
});
|
13727
|
+
def_is_bigint(AST_Assign, function(compressor) {
|
13728
|
+
return (numeric_ops.has(this.operator.slice(0, -1)) || this.operator == "=")
|
13729
|
+
&& this.right.is_bigint(compressor);
|
13730
|
+
});
|
13731
|
+
def_is_bigint(AST_Sequence, function(compressor) {
|
13732
|
+
return this.tail_node().is_bigint(compressor);
|
13733
|
+
});
|
13734
|
+
def_is_bigint(AST_Conditional, function(compressor) {
|
13735
|
+
return this.consequent.is_bigint(compressor) && this.alternative.is_bigint(compressor);
|
13736
|
+
});
|
13737
|
+
})(function(node, func) {
|
13738
|
+
node.DEFMETHOD("is_bigint", func);
|
13739
|
+
});
|
13740
|
+
|
13741
|
+
// methods to determine if an expression is a number or a bigint
|
13742
|
+
(function(def_is_number_or_bigint) {
|
13743
|
+
def_is_number_or_bigint(AST_Node, return_false);
|
13744
|
+
def_is_number_or_bigint(AST_Number, return_true);
|
13745
|
+
def_is_number_or_bigint(AST_BigInt, return_true);
|
13746
|
+
const numeric_unary_ops = makePredicate("+ - ~ ++ --");
|
13747
|
+
def_is_number_or_bigint(AST_Unary, function(_compressor) {
|
13748
|
+
return numeric_unary_ops.has(this.operator);
|
13749
|
+
});
|
13750
|
+
const numeric_ops = makePredicate("- * / % & | ^ << >>");
|
13751
|
+
def_is_number_or_bigint(AST_Binary, function(compressor) {
|
13752
|
+
return this.operator === "+"
|
13753
|
+
? this.left.is_number_or_bigint(compressor) && this.right.is_number_or_bigint(compressor)
|
13754
|
+
: numeric_ops.has(this.operator);
|
13755
|
+
});
|
13756
|
+
def_is_number_or_bigint(AST_Assign, function(compressor) {
|
13757
|
+
return numeric_ops.has(this.operator.slice(0, -1))
|
13758
|
+
|| this.operator == "=" && this.right.is_number_or_bigint(compressor);
|
13759
|
+
});
|
13760
|
+
def_is_number_or_bigint(AST_Sequence, function(compressor) {
|
13761
|
+
return this.tail_node().is_number_or_bigint(compressor);
|
13762
|
+
});
|
13763
|
+
def_is_number_or_bigint(AST_Conditional, function(compressor) {
|
13764
|
+
return this.consequent.is_number_or_bigint(compressor) && this.alternative.is_number_or_bigint(compressor);
|
13765
|
+
});
|
13766
|
+
}(function (node, func) {
|
13767
|
+
node.DEFMETHOD("is_number_or_bigint", func);
|
13768
|
+
}));
|
13769
|
+
|
13770
|
+
|
13702
13771
|
// 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
|
13703
13772
|
(function(def_is_32_bit_integer) {
|
13704
13773
|
def_is_32_bit_integer(AST_Node, return_false);
|
13705
|
-
def_is_32_bit_integer(AST_Number, function() {
|
13774
|
+
def_is_32_bit_integer(AST_Number, function(_compressor) {
|
13706
13775
|
return this.value === (this.value | 0);
|
13707
13776
|
});
|
13708
|
-
def_is_32_bit_integer(AST_UnaryPrefix, function() {
|
13709
|
-
return this.operator == "~" ? this.expression.is_number()
|
13710
|
-
: this.operator === "+" ? this.expression.is_32_bit_integer()
|
13777
|
+
def_is_32_bit_integer(AST_UnaryPrefix, function(compressor) {
|
13778
|
+
return this.operator == "~" ? this.expression.is_number(compressor)
|
13779
|
+
: this.operator === "+" ? this.expression.is_32_bit_integer(compressor)
|
13711
13780
|
: false;
|
13712
13781
|
});
|
13713
|
-
def_is_32_bit_integer(AST_Binary, function() {
|
13714
|
-
return bitwise_binop.has(this.operator)
|
13782
|
+
def_is_32_bit_integer(AST_Binary, function(compressor) {
|
13783
|
+
return bitwise_binop.has(this.operator)
|
13784
|
+
&& (this.left.is_number(compressor) || this.right.is_number(compressor));
|
13715
13785
|
});
|
13716
13786
|
}(function (node, func) {
|
13717
13787
|
node.DEFMETHOD("is_32_bit_integer", func);
|
@@ -14348,30 +14418,36 @@ function is_lhs(node, parent) {
|
|
14348
14418
|
});
|
14349
14419
|
|
14350
14420
|
(function (def_bitwise_negate) {
|
14351
|
-
function
|
14421
|
+
function basic_bitwise_negation(exp) {
|
14352
14422
|
return make_node(AST_UnaryPrefix, exp, {
|
14353
14423
|
operator: "~",
|
14354
14424
|
expression: exp
|
14355
14425
|
});
|
14356
14426
|
}
|
14357
14427
|
|
14358
|
-
def_bitwise_negate(AST_Node, function() {
|
14359
|
-
return
|
14428
|
+
def_bitwise_negate(AST_Node, function(_compressor) {
|
14429
|
+
return basic_bitwise_negation(this);
|
14360
14430
|
});
|
14361
14431
|
|
14362
|
-
def_bitwise_negate(AST_Number, function() {
|
14432
|
+
def_bitwise_negate(AST_Number, function(_compressor) {
|
14363
14433
|
const neg = ~this.value;
|
14364
14434
|
if (neg.toString().length > this.value.toString().length) {
|
14365
|
-
return
|
14435
|
+
return basic_bitwise_negation(this);
|
14366
14436
|
}
|
14367
14437
|
return make_node(AST_Number, this, { value: neg });
|
14368
14438
|
});
|
14369
14439
|
|
14370
|
-
def_bitwise_negate(AST_UnaryPrefix, function(in_32_bit_context) {
|
14371
|
-
if (
|
14440
|
+
def_bitwise_negate(AST_UnaryPrefix, function(compressor, in_32_bit_context) {
|
14441
|
+
if (
|
14442
|
+
this.operator == "~"
|
14443
|
+
&& (
|
14444
|
+
this.expression.is_32_bit_integer(compressor) ||
|
14445
|
+
(in_32_bit_context != null ? in_32_bit_context : compressor.in_32_bit_context())
|
14446
|
+
)
|
14447
|
+
) {
|
14372
14448
|
return this.expression;
|
14373
14449
|
} else {
|
14374
|
-
return
|
14450
|
+
return basic_bitwise_negation(this);
|
14375
14451
|
}
|
14376
14452
|
});
|
14377
14453
|
})(function (node, func) {
|
@@ -18908,12 +18984,16 @@ class Compressor extends TreeWalker {
|
|
18908
18984
|
}
|
18909
18985
|
}
|
18910
18986
|
|
18911
|
-
in_32_bit_context() {
|
18987
|
+
in_32_bit_context(other_operand_must_be_number) {
|
18912
18988
|
if (!this.option("evaluate")) return false;
|
18913
18989
|
var self = this.self();
|
18914
18990
|
for (var i = 0, p; p = this.parent(i); i++) {
|
18915
18991
|
if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) {
|
18916
|
-
|
18992
|
+
if (other_operand_must_be_number) {
|
18993
|
+
return (self === p.left ? p.right : p.left).is_number(this);
|
18994
|
+
} else {
|
18995
|
+
return true;
|
18996
|
+
}
|
18917
18997
|
}
|
18918
18998
|
if (p instanceof AST_UnaryPrefix) {
|
18919
18999
|
return p.operator === "~";
|
@@ -20684,7 +20764,7 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) {
|
|
20684
20764
|
self.operator === "~"
|
20685
20765
|
&& self.expression instanceof AST_UnaryPrefix
|
20686
20766
|
&& self.expression.operator === "~"
|
20687
|
-
&& (compressor.in_32_bit_context() || self.expression.expression.is_32_bit_integer())
|
20767
|
+
&& (compressor.in_32_bit_context(false) || self.expression.expression.is_32_bit_integer(compressor))
|
20688
20768
|
) {
|
20689
20769
|
return self.expression.expression;
|
20690
20770
|
}
|
@@ -20697,9 +20777,9 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) {
|
|
20697
20777
|
) {
|
20698
20778
|
if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") {
|
20699
20779
|
// ~(~x ^ y) => x ^ y
|
20700
|
-
e.left = e.left.bitwise_negate(true);
|
20780
|
+
e.left = e.left.bitwise_negate(compressor, true);
|
20701
20781
|
} else {
|
20702
|
-
e.right = e.right.bitwise_negate(true);
|
20782
|
+
e.right = e.right.bitwise_negate(compressor, true);
|
20703
20783
|
}
|
20704
20784
|
return e;
|
20705
20785
|
}
|
@@ -20794,10 +20874,13 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
20794
20874
|
case "===":
|
20795
20875
|
case "!==":
|
20796
20876
|
var is_strict_comparison = true;
|
20797
|
-
if (
|
20877
|
+
if (
|
20878
|
+
(self.left.is_string(compressor) && self.right.is_string(compressor)) ||
|
20798
20879
|
(self.left.is_number(compressor) && self.right.is_number(compressor)) ||
|
20880
|
+
(self.left.is_bigint(compressor) && self.right.is_bigint(compressor)) ||
|
20799
20881
|
(self.left.is_boolean() && self.right.is_boolean()) ||
|
20800
|
-
self.left.equivalent_to(self.right)
|
20882
|
+
self.left.equivalent_to(self.right)
|
20883
|
+
) {
|
20801
20884
|
self.operator = self.operator.substr(0, 2);
|
20802
20885
|
}
|
20803
20886
|
|
@@ -20842,7 +20925,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
20842
20925
|
&& self.left.definition() === self.right.definition()
|
20843
20926
|
&& is_object(self.left.fixed_value())) {
|
20844
20927
|
return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
|
20845
|
-
} else if (self.left.is_32_bit_integer() && self.right.is_32_bit_integer()) {
|
20928
|
+
} else if (self.left.is_32_bit_integer(compressor) && self.right.is_32_bit_integer(compressor)) {
|
20846
20929
|
const not = node => make_node(AST_UnaryPrefix, node, {
|
20847
20930
|
operator: "!",
|
20848
20931
|
expression: node
|
@@ -20875,7 +20958,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
20875
20958
|
&& (mask = and_op === self.left ? self.right : self.left)
|
20876
20959
|
&& and_op.operator === "&"
|
20877
20960
|
&& mask instanceof AST_Number
|
20878
|
-
&& mask.is_32_bit_integer()
|
20961
|
+
&& mask.is_32_bit_integer(compressor)
|
20879
20962
|
&& (x =
|
20880
20963
|
and_op.left.equivalent_to(mask) ? and_op.right
|
20881
20964
|
: and_op.right.equivalent_to(mask) ? and_op.left : null)
|
@@ -21118,7 +21201,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21118
21201
|
// a + -b => a - b
|
21119
21202
|
if (self.right instanceof AST_UnaryPrefix
|
21120
21203
|
&& self.right.operator == "-"
|
21121
|
-
&& self.left.
|
21204
|
+
&& self.left.is_number_or_bigint(compressor)) {
|
21122
21205
|
self = make_node(AST_Binary, self, {
|
21123
21206
|
operator: "-",
|
21124
21207
|
left: self.left,
|
@@ -21130,7 +21213,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21130
21213
|
if (self.left instanceof AST_UnaryPrefix
|
21131
21214
|
&& self.left.operator == "-"
|
21132
21215
|
&& reversible()
|
21133
|
-
&& self.right.
|
21216
|
+
&& self.right.is_number_or_bigint(compressor)) {
|
21134
21217
|
self = make_node(AST_Binary, self, {
|
21135
21218
|
operator: "-",
|
21136
21219
|
left: self.right,
|
@@ -21174,8 +21257,9 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21174
21257
|
case "|":
|
21175
21258
|
case "^":
|
21176
21259
|
// a + +b => +b + a
|
21177
|
-
if (
|
21178
|
-
|
21260
|
+
if (
|
21261
|
+
self.left.is_number_or_bigint(compressor)
|
21262
|
+
&& self.right.is_number_or_bigint(compressor)
|
21179
21263
|
&& reversible()
|
21180
21264
|
&& !(self.left instanceof AST_Binary
|
21181
21265
|
&& self.left.operator != self.operator
|
@@ -21192,7 +21276,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21192
21276
|
self = best_of(compressor, self, reversed);
|
21193
21277
|
}
|
21194
21278
|
}
|
21195
|
-
if (associative && self.
|
21279
|
+
if (associative && self.is_number_or_bigint(compressor)) {
|
21196
21280
|
// a + (b + c) => (a + b) + c
|
21197
21281
|
if (self.right instanceof AST_Binary
|
21198
21282
|
&& self.right.operator == self.operator) {
|
@@ -21311,18 +21395,31 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21311
21395
|
}
|
21312
21396
|
}
|
21313
21397
|
|
21314
|
-
// x ^ x => 0
|
21315
21398
|
// x | x => 0 | x
|
21316
21399
|
// x & x => 0 | x
|
21317
|
-
|
21318
|
-
|
21319
|
-
|
21320
|
-
|
21321
|
-
|
21322
|
-
|
21323
|
-
|
21324
|
-
|
21325
|
-
|
21400
|
+
if (
|
21401
|
+
(self.operator === "|" || self.operator === "&")
|
21402
|
+
&& self.left.equivalent_to(self.right)
|
21403
|
+
&& !self.left.has_side_effects(compressor)
|
21404
|
+
&& compressor.in_32_bit_context(true)
|
21405
|
+
) {
|
21406
|
+
self.left = make_node(AST_Number, self, { value: 0 });
|
21407
|
+
self.operator = "|";
|
21408
|
+
}
|
21409
|
+
|
21410
|
+
// ~x ^ ~y => x ^ y
|
21411
|
+
if (
|
21412
|
+
self.operator === "^"
|
21413
|
+
&& self.left instanceof AST_UnaryPrefix
|
21414
|
+
&& self.left.operator === "~"
|
21415
|
+
&& self.right instanceof AST_UnaryPrefix
|
21416
|
+
&& self.right.operator === "~"
|
21417
|
+
) {
|
21418
|
+
self = make_node(AST_Binary, self, {
|
21419
|
+
operator: "^",
|
21420
|
+
left: self.left.expression,
|
21421
|
+
right: self.right.expression
|
21422
|
+
});
|
21326
21423
|
}
|
21327
21424
|
|
21328
21425
|
|
@@ -21346,7 +21443,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21346
21443
|
if (
|
21347
21444
|
zero_side
|
21348
21445
|
&& (self.operator === "|" || self.operator === "^")
|
21349
|
-
&& (non_zero_side.is_32_bit_integer() || compressor.in_32_bit_context())
|
21446
|
+
&& (non_zero_side.is_32_bit_integer(compressor) || compressor.in_32_bit_context(true))
|
21350
21447
|
) {
|
21351
21448
|
return non_zero_side;
|
21352
21449
|
}
|
@@ -21356,65 +21453,48 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
21356
21453
|
zero_side
|
21357
21454
|
&& self.operator === "&"
|
21358
21455
|
&& !non_zero_side.has_side_effects(compressor)
|
21456
|
+
&& non_zero_side.is_32_bit_integer(compressor)
|
21359
21457
|
) {
|
21360
21458
|
return zero_side;
|
21361
21459
|
}
|
21362
21460
|
|
21461
|
+
// ~0 is all ones, as well as -1.
|
21462
|
+
// We can ellide some operations with it.
|
21363
21463
|
const is_full_mask = (node) =>
|
21364
21464
|
node instanceof AST_Number && node.value === -1
|
21365
21465
|
||
|
21366
|
-
node instanceof AST_UnaryPrefix
|
21367
|
-
|
21368
|
-
|
21369
|
-
|
21370
|
-
|| node.operator === "~"
|
21371
|
-
&& node.expression instanceof AST_Number
|
21372
|
-
&& node.expression.value === 0);
|
21466
|
+
node instanceof AST_UnaryPrefix
|
21467
|
+
&& node.operator === "-"
|
21468
|
+
&& node.expression instanceof AST_Number
|
21469
|
+
&& node.expression.value === 1;
|
21373
21470
|
|
21374
21471
|
const full_mask = is_full_mask(self.right) ? self.right
|
21375
21472
|
: is_full_mask(self.left) ? self.left
|
21376
21473
|
: null;
|
21377
|
-
const
|
21378
|
-
|
21379
|
-
switch (self.operator) {
|
21380
|
-
case "|":
|
21381
|
-
// {anything} | -1 => -1
|
21382
|
-
if (full_mask && !non_full_mask_side.has_side_effects(compressor)) {
|
21383
|
-
return full_mask;
|
21384
|
-
}
|
21474
|
+
const other_side = (full_mask === self.right ? self.left : self.right);
|
21385
21475
|
|
21386
|
-
|
21387
|
-
|
21388
|
-
|
21389
|
-
|
21390
|
-
|
21391
|
-
|
21392
|
-
|
21393
|
-
|
21394
|
-
|
21395
|
-
|
21396
|
-
|
21397
|
-
case "^":
|
21398
|
-
// {anything} ^ -1 => ~{anything}
|
21399
|
-
if (full_mask) {
|
21400
|
-
return non_full_mask_side.bitwise_negate(compressor.in_32_bit_context());
|
21401
|
-
}
|
21402
|
-
|
21403
|
-
// ~x ^ ~y => x ^ y
|
21404
|
-
if (
|
21405
|
-
self.left instanceof AST_UnaryPrefix
|
21406
|
-
&& self.left.operator === "~"
|
21407
|
-
&& self.right instanceof AST_UnaryPrefix
|
21408
|
-
&& self.right.operator === "~"
|
21409
|
-
) {
|
21410
|
-
self = make_node(AST_Binary, self, {
|
21411
|
-
operator: "^",
|
21412
|
-
left: self.left.expression,
|
21413
|
-
right: self.right.expression
|
21414
|
-
});
|
21415
|
-
}
|
21476
|
+
// {32 bit integer} & -1 => {32 bit integer}
|
21477
|
+
if (
|
21478
|
+
full_mask
|
21479
|
+
&& self.operator === "&"
|
21480
|
+
&& (
|
21481
|
+
other_side.is_32_bit_integer(compressor)
|
21482
|
+
|| compressor.in_32_bit_context(true)
|
21483
|
+
)
|
21484
|
+
) {
|
21485
|
+
return other_side;
|
21486
|
+
}
|
21416
21487
|
|
21417
|
-
|
21488
|
+
// {anything} ^ -1 => ~{anything}
|
21489
|
+
if (
|
21490
|
+
full_mask
|
21491
|
+
&& self.operator === "^"
|
21492
|
+
&& (
|
21493
|
+
other_side.is_32_bit_integer(compressor)
|
21494
|
+
|| compressor.in_32_bit_context(true)
|
21495
|
+
)
|
21496
|
+
) {
|
21497
|
+
return other_side.bitwise_negate(compressor);
|
21418
21498
|
}
|
21419
21499
|
}
|
21420
21500
|
}
|
@@ -22465,7 +22545,7 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
22465
22545
|
&& segments[1] instanceof AST_Node
|
22466
22546
|
&& (
|
22467
22547
|
segments[1].is_string(compressor)
|
22468
|
-
|| segments[1].
|
22548
|
+
|| segments[1].is_number_or_bigint(compressor)
|
22469
22549
|
|| is_nullish(segments[1], compressor)
|
22470
22550
|
|| compressor.option("unsafe")
|
22471
22551
|
)
|
package/lib/compress/index.js
CHANGED
@@ -376,12 +376,16 @@ class Compressor extends TreeWalker {
|
|
376
376
|
}
|
377
377
|
}
|
378
378
|
|
379
|
-
in_32_bit_context() {
|
379
|
+
in_32_bit_context(other_operand_must_be_number) {
|
380
380
|
if (!this.option("evaluate")) return false;
|
381
381
|
var self = this.self();
|
382
382
|
for (var i = 0, p; p = this.parent(i); i++) {
|
383
383
|
if (p instanceof AST_Binary && bitwise_binop.has(p.operator)) {
|
384
|
-
|
384
|
+
if (other_operand_must_be_number) {
|
385
|
+
return (self === p.left ? p.right : p.left).is_number(this);
|
386
|
+
} else {
|
387
|
+
return true;
|
388
|
+
}
|
385
389
|
}
|
386
390
|
if (p instanceof AST_UnaryPrefix) {
|
387
391
|
return p.operator === "~";
|
@@ -2152,7 +2156,7 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) {
|
|
2152
2156
|
self.operator === "~"
|
2153
2157
|
&& self.expression instanceof AST_UnaryPrefix
|
2154
2158
|
&& self.expression.operator === "~"
|
2155
|
-
&& (compressor.in_32_bit_context() || self.expression.expression.is_32_bit_integer())
|
2159
|
+
&& (compressor.in_32_bit_context(false) || self.expression.expression.is_32_bit_integer(compressor))
|
2156
2160
|
) {
|
2157
2161
|
return self.expression.expression;
|
2158
2162
|
}
|
@@ -2165,9 +2169,9 @@ def_optimize(AST_UnaryPrefix, function(self, compressor) {
|
|
2165
2169
|
) {
|
2166
2170
|
if (e.left instanceof AST_UnaryPrefix && e.left.operator === "~") {
|
2167
2171
|
// ~(~x ^ y) => x ^ y
|
2168
|
-
e.left = e.left.bitwise_negate(true);
|
2172
|
+
e.left = e.left.bitwise_negate(compressor, true);
|
2169
2173
|
} else {
|
2170
|
-
e.right = e.right.bitwise_negate(true);
|
2174
|
+
e.right = e.right.bitwise_negate(compressor, true);
|
2171
2175
|
}
|
2172
2176
|
return e;
|
2173
2177
|
}
|
@@ -2262,10 +2266,13 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2262
2266
|
case "===":
|
2263
2267
|
case "!==":
|
2264
2268
|
var is_strict_comparison = true;
|
2265
|
-
if (
|
2269
|
+
if (
|
2270
|
+
(self.left.is_string(compressor) && self.right.is_string(compressor)) ||
|
2266
2271
|
(self.left.is_number(compressor) && self.right.is_number(compressor)) ||
|
2272
|
+
(self.left.is_bigint(compressor) && self.right.is_bigint(compressor)) ||
|
2267
2273
|
(self.left.is_boolean() && self.right.is_boolean()) ||
|
2268
|
-
self.left.equivalent_to(self.right)
|
2274
|
+
self.left.equivalent_to(self.right)
|
2275
|
+
) {
|
2269
2276
|
self.operator = self.operator.substr(0, 2);
|
2270
2277
|
}
|
2271
2278
|
|
@@ -2310,7 +2317,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2310
2317
|
&& self.left.definition() === self.right.definition()
|
2311
2318
|
&& is_object(self.left.fixed_value())) {
|
2312
2319
|
return make_node(self.operator[0] == "=" ? AST_True : AST_False, self);
|
2313
|
-
} else if (self.left.is_32_bit_integer() && self.right.is_32_bit_integer()) {
|
2320
|
+
} else if (self.left.is_32_bit_integer(compressor) && self.right.is_32_bit_integer(compressor)) {
|
2314
2321
|
const not = node => make_node(AST_UnaryPrefix, node, {
|
2315
2322
|
operator: "!",
|
2316
2323
|
expression: node
|
@@ -2343,7 +2350,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2343
2350
|
&& (mask = and_op === self.left ? self.right : self.left)
|
2344
2351
|
&& and_op.operator === "&"
|
2345
2352
|
&& mask instanceof AST_Number
|
2346
|
-
&& mask.is_32_bit_integer()
|
2353
|
+
&& mask.is_32_bit_integer(compressor)
|
2347
2354
|
&& (x =
|
2348
2355
|
and_op.left.equivalent_to(mask) ? and_op.right
|
2349
2356
|
: and_op.right.equivalent_to(mask) ? and_op.left : null)
|
@@ -2586,7 +2593,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2586
2593
|
// a + -b => a - b
|
2587
2594
|
if (self.right instanceof AST_UnaryPrefix
|
2588
2595
|
&& self.right.operator == "-"
|
2589
|
-
&& self.left.
|
2596
|
+
&& self.left.is_number_or_bigint(compressor)) {
|
2590
2597
|
self = make_node(AST_Binary, self, {
|
2591
2598
|
operator: "-",
|
2592
2599
|
left: self.left,
|
@@ -2598,7 +2605,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2598
2605
|
if (self.left instanceof AST_UnaryPrefix
|
2599
2606
|
&& self.left.operator == "-"
|
2600
2607
|
&& reversible()
|
2601
|
-
&& self.right.
|
2608
|
+
&& self.right.is_number_or_bigint(compressor)) {
|
2602
2609
|
self = make_node(AST_Binary, self, {
|
2603
2610
|
operator: "-",
|
2604
2611
|
left: self.right,
|
@@ -2642,8 +2649,9 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2642
2649
|
case "|":
|
2643
2650
|
case "^":
|
2644
2651
|
// a + +b => +b + a
|
2645
|
-
if (
|
2646
|
-
|
2652
|
+
if (
|
2653
|
+
self.left.is_number_or_bigint(compressor)
|
2654
|
+
&& self.right.is_number_or_bigint(compressor)
|
2647
2655
|
&& reversible()
|
2648
2656
|
&& !(self.left instanceof AST_Binary
|
2649
2657
|
&& self.left.operator != self.operator
|
@@ -2660,7 +2668,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2660
2668
|
self = best_of(compressor, self, reversed);
|
2661
2669
|
}
|
2662
2670
|
}
|
2663
|
-
if (associative && self.
|
2671
|
+
if (associative && self.is_number_or_bigint(compressor)) {
|
2664
2672
|
// a + (b + c) => (a + b) + c
|
2665
2673
|
if (self.right instanceof AST_Binary
|
2666
2674
|
&& self.right.operator == self.operator) {
|
@@ -2779,18 +2787,31 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2779
2787
|
}
|
2780
2788
|
}
|
2781
2789
|
|
2782
|
-
// x ^ x => 0
|
2783
2790
|
// x | x => 0 | x
|
2784
2791
|
// x & x => 0 | x
|
2785
|
-
|
2786
|
-
|
2787
|
-
|
2788
|
-
|
2789
|
-
|
2790
|
-
|
2791
|
-
|
2792
|
-
|
2793
|
-
|
2792
|
+
if (
|
2793
|
+
(self.operator === "|" || self.operator === "&")
|
2794
|
+
&& self.left.equivalent_to(self.right)
|
2795
|
+
&& !self.left.has_side_effects(compressor)
|
2796
|
+
&& compressor.in_32_bit_context(true)
|
2797
|
+
) {
|
2798
|
+
self.left = make_node(AST_Number, self, { value: 0 });
|
2799
|
+
self.operator = "|";
|
2800
|
+
}
|
2801
|
+
|
2802
|
+
// ~x ^ ~y => x ^ y
|
2803
|
+
if (
|
2804
|
+
self.operator === "^"
|
2805
|
+
&& self.left instanceof AST_UnaryPrefix
|
2806
|
+
&& self.left.operator === "~"
|
2807
|
+
&& self.right instanceof AST_UnaryPrefix
|
2808
|
+
&& self.right.operator === "~"
|
2809
|
+
) {
|
2810
|
+
self = make_node(AST_Binary, self, {
|
2811
|
+
operator: "^",
|
2812
|
+
left: self.left.expression,
|
2813
|
+
right: self.right.expression
|
2814
|
+
});
|
2794
2815
|
}
|
2795
2816
|
|
2796
2817
|
|
@@ -2814,7 +2835,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2814
2835
|
if (
|
2815
2836
|
zero_side
|
2816
2837
|
&& (self.operator === "|" || self.operator === "^")
|
2817
|
-
&& (non_zero_side.is_32_bit_integer() || compressor.in_32_bit_context())
|
2838
|
+
&& (non_zero_side.is_32_bit_integer(compressor) || compressor.in_32_bit_context(true))
|
2818
2839
|
) {
|
2819
2840
|
return non_zero_side;
|
2820
2841
|
}
|
@@ -2824,65 +2845,48 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
2824
2845
|
zero_side
|
2825
2846
|
&& self.operator === "&"
|
2826
2847
|
&& !non_zero_side.has_side_effects(compressor)
|
2848
|
+
&& non_zero_side.is_32_bit_integer(compressor)
|
2827
2849
|
) {
|
2828
2850
|
return zero_side;
|
2829
2851
|
}
|
2830
2852
|
|
2853
|
+
// ~0 is all ones, as well as -1.
|
2854
|
+
// We can ellide some operations with it.
|
2831
2855
|
const is_full_mask = (node) =>
|
2832
2856
|
node instanceof AST_Number && node.value === -1
|
2833
2857
|
||
|
2834
|
-
node instanceof AST_UnaryPrefix
|
2835
|
-
|
2836
|
-
|
2837
|
-
|
2838
|
-
|| node.operator === "~"
|
2839
|
-
&& node.expression instanceof AST_Number
|
2840
|
-
&& node.expression.value === 0);
|
2858
|
+
node instanceof AST_UnaryPrefix
|
2859
|
+
&& node.operator === "-"
|
2860
|
+
&& node.expression instanceof AST_Number
|
2861
|
+
&& node.expression.value === 1;
|
2841
2862
|
|
2842
2863
|
const full_mask = is_full_mask(self.right) ? self.right
|
2843
2864
|
: is_full_mask(self.left) ? self.left
|
2844
2865
|
: null;
|
2845
|
-
const
|
2866
|
+
const other_side = (full_mask === self.right ? self.left : self.right);
|
2846
2867
|
|
2847
|
-
|
2848
|
-
|
2849
|
-
|
2850
|
-
|
2851
|
-
|
2852
|
-
|
2853
|
-
|
2854
|
-
|
2855
|
-
|
2856
|
-
|
2857
|
-
|
2858
|
-
full_mask
|
2859
|
-
&& (non_full_mask_side.is_32_bit_integer() || compressor.in_32_bit_context())
|
2860
|
-
) {
|
2861
|
-
return non_full_mask_side;
|
2862
|
-
}
|
2863
|
-
|
2864
|
-
break;
|
2865
|
-
case "^":
|
2866
|
-
// {anything} ^ -1 => ~{anything}
|
2867
|
-
if (full_mask) {
|
2868
|
-
return non_full_mask_side.bitwise_negate(compressor.in_32_bit_context());
|
2869
|
-
}
|
2870
|
-
|
2871
|
-
// ~x ^ ~y => x ^ y
|
2872
|
-
if (
|
2873
|
-
self.left instanceof AST_UnaryPrefix
|
2874
|
-
&& self.left.operator === "~"
|
2875
|
-
&& self.right instanceof AST_UnaryPrefix
|
2876
|
-
&& self.right.operator === "~"
|
2877
|
-
) {
|
2878
|
-
self = make_node(AST_Binary, self, {
|
2879
|
-
operator: "^",
|
2880
|
-
left: self.left.expression,
|
2881
|
-
right: self.right.expression
|
2882
|
-
});
|
2883
|
-
}
|
2868
|
+
// {32 bit integer} & -1 => {32 bit integer}
|
2869
|
+
if (
|
2870
|
+
full_mask
|
2871
|
+
&& self.operator === "&"
|
2872
|
+
&& (
|
2873
|
+
other_side.is_32_bit_integer(compressor)
|
2874
|
+
|| compressor.in_32_bit_context(true)
|
2875
|
+
)
|
2876
|
+
) {
|
2877
|
+
return other_side;
|
2878
|
+
}
|
2884
2879
|
|
2885
|
-
|
2880
|
+
// {anything} ^ -1 => ~{anything}
|
2881
|
+
if (
|
2882
|
+
full_mask
|
2883
|
+
&& self.operator === "^"
|
2884
|
+
&& (
|
2885
|
+
other_side.is_32_bit_integer(compressor)
|
2886
|
+
|| compressor.in_32_bit_context(true)
|
2887
|
+
)
|
2888
|
+
) {
|
2889
|
+
return other_side.bitwise_negate(compressor);
|
2886
2890
|
}
|
2887
2891
|
}
|
2888
2892
|
}
|
@@ -3933,7 +3937,7 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
3933
3937
|
&& segments[1] instanceof AST_Node
|
3934
3938
|
&& (
|
3935
3939
|
segments[1].is_string(compressor)
|
3936
|
-
|| segments[1].
|
3940
|
+
|| segments[1].is_number_or_bigint(compressor)
|
3937
3941
|
|| is_nullish(segments[1], compressor)
|
3938
3942
|
|| compressor.option("unsafe")
|
3939
3943
|
)
|
@@ -175,18 +175,24 @@ export const unary_side_effects = makePredicate("delete ++ --");
|
|
175
175
|
def_is_number(AST_Node, return_false);
|
176
176
|
def_is_number(AST_Number, return_true);
|
177
177
|
const unary = makePredicate("+ - ~ ++ --");
|
178
|
-
def_is_number(AST_Unary, function() {
|
179
|
-
return unary.has(this.operator) &&
|
178
|
+
def_is_number(AST_Unary, function(compressor) {
|
179
|
+
return unary.has(this.operator) && this.expression.is_number(compressor);
|
180
180
|
});
|
181
181
|
const numeric_ops = makePredicate("- * / % & | ^ << >> >>>");
|
182
182
|
def_is_number(AST_Binary, function(compressor) {
|
183
|
-
|
184
|
-
|
185
|
-
&& this.right.
|
183
|
+
if (this.operator === "+") {
|
184
|
+
// Both sides need to be `number`. Or one is a `number` and the other is number-ish.
|
185
|
+
return this.left.is_number(compressor) && this.right.is_number_or_bigint(compressor)
|
186
|
+
|| this.right.is_number(compressor) && this.left.is_number_or_bigint(compressor);
|
187
|
+
} else if (numeric_ops.has(this.operator)) {
|
188
|
+
return this.left.is_number(compressor) || this.right.is_number(compressor);
|
189
|
+
} else {
|
190
|
+
return false;
|
191
|
+
}
|
186
192
|
});
|
187
193
|
def_is_number(AST_Assign, function(compressor) {
|
188
|
-
return numeric_ops.has(this.operator.slice(0, -1))
|
189
|
-
|
194
|
+
return (this.operator === "=" || numeric_ops.has(this.operator.slice(0, -1)))
|
195
|
+
&& this.right.is_number(compressor);
|
190
196
|
});
|
191
197
|
def_is_number(AST_Sequence, function(compressor) {
|
192
198
|
return this.tail_node().is_number(compressor);
|
@@ -198,19 +204,83 @@ export const unary_side_effects = makePredicate("delete ++ --");
|
|
198
204
|
node.DEFMETHOD("is_number", func);
|
199
205
|
});
|
200
206
|
|
207
|
+
// methods to determine if an expression returns a BigInt
|
208
|
+
(function(def_is_bigint) {
|
209
|
+
def_is_bigint(AST_Node, return_false);
|
210
|
+
def_is_bigint(AST_BigInt, return_true);
|
211
|
+
const unary = makePredicate("+ - ~ ++ --");
|
212
|
+
def_is_bigint(AST_Unary, function(compressor) {
|
213
|
+
return unary.has(this.operator) && this.expression.is_bigint(compressor);
|
214
|
+
});
|
215
|
+
const numeric_ops = makePredicate("- * / % & | ^ << >>");
|
216
|
+
def_is_bigint(AST_Binary, function(compressor) {
|
217
|
+
if (this.operator === "+") {
|
218
|
+
return this.left.is_bigint(compressor) && this.right.is_number_or_bigint(compressor)
|
219
|
+
|| this.right.is_bigint(compressor) && this.left.is_number_or_bigint(compressor);
|
220
|
+
} else if (numeric_ops.has(this.operator)) {
|
221
|
+
return this.left.is_bigint(compressor) || this.right.is_bigint(compressor);
|
222
|
+
} else {
|
223
|
+
return false;
|
224
|
+
}
|
225
|
+
});
|
226
|
+
def_is_bigint(AST_Assign, function(compressor) {
|
227
|
+
return (numeric_ops.has(this.operator.slice(0, -1)) || this.operator == "=")
|
228
|
+
&& this.right.is_bigint(compressor);
|
229
|
+
});
|
230
|
+
def_is_bigint(AST_Sequence, function(compressor) {
|
231
|
+
return this.tail_node().is_bigint(compressor);
|
232
|
+
});
|
233
|
+
def_is_bigint(AST_Conditional, function(compressor) {
|
234
|
+
return this.consequent.is_bigint(compressor) && this.alternative.is_bigint(compressor);
|
235
|
+
});
|
236
|
+
})(function(node, func) {
|
237
|
+
node.DEFMETHOD("is_bigint", func);
|
238
|
+
});
|
239
|
+
|
240
|
+
// methods to determine if an expression is a number or a bigint
|
241
|
+
(function(def_is_number_or_bigint) {
|
242
|
+
def_is_number_or_bigint(AST_Node, return_false);
|
243
|
+
def_is_number_or_bigint(AST_Number, return_true);
|
244
|
+
def_is_number_or_bigint(AST_BigInt, return_true);
|
245
|
+
const numeric_unary_ops = makePredicate("+ - ~ ++ --");
|
246
|
+
def_is_number_or_bigint(AST_Unary, function(_compressor) {
|
247
|
+
return numeric_unary_ops.has(this.operator);
|
248
|
+
});
|
249
|
+
const numeric_ops = makePredicate("- * / % & | ^ << >>");
|
250
|
+
def_is_number_or_bigint(AST_Binary, function(compressor) {
|
251
|
+
return this.operator === "+"
|
252
|
+
? this.left.is_number_or_bigint(compressor) && this.right.is_number_or_bigint(compressor)
|
253
|
+
: numeric_ops.has(this.operator);
|
254
|
+
});
|
255
|
+
def_is_number_or_bigint(AST_Assign, function(compressor) {
|
256
|
+
return numeric_ops.has(this.operator.slice(0, -1))
|
257
|
+
|| this.operator == "=" && this.right.is_number_or_bigint(compressor);
|
258
|
+
});
|
259
|
+
def_is_number_or_bigint(AST_Sequence, function(compressor) {
|
260
|
+
return this.tail_node().is_number_or_bigint(compressor);
|
261
|
+
});
|
262
|
+
def_is_number_or_bigint(AST_Conditional, function(compressor) {
|
263
|
+
return this.consequent.is_number_or_bigint(compressor) && this.alternative.is_number_or_bigint(compressor);
|
264
|
+
});
|
265
|
+
}(function (node, func) {
|
266
|
+
node.DEFMETHOD("is_number_or_bigint", func);
|
267
|
+
}));
|
268
|
+
|
269
|
+
|
201
270
|
// 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
|
202
271
|
(function(def_is_32_bit_integer) {
|
203
272
|
def_is_32_bit_integer(AST_Node, return_false);
|
204
|
-
def_is_32_bit_integer(AST_Number, function() {
|
273
|
+
def_is_32_bit_integer(AST_Number, function(_compressor) {
|
205
274
|
return this.value === (this.value | 0);
|
206
275
|
});
|
207
|
-
def_is_32_bit_integer(AST_UnaryPrefix, function() {
|
208
|
-
return this.operator == "~" ? this.expression.is_number()
|
209
|
-
: this.operator === "+" ? this.expression.is_32_bit_integer()
|
276
|
+
def_is_32_bit_integer(AST_UnaryPrefix, function(compressor) {
|
277
|
+
return this.operator == "~" ? this.expression.is_number(compressor)
|
278
|
+
: this.operator === "+" ? this.expression.is_32_bit_integer(compressor)
|
210
279
|
: false;
|
211
280
|
});
|
212
|
-
def_is_32_bit_integer(AST_Binary, function() {
|
213
|
-
return bitwise_binop.has(this.operator)
|
281
|
+
def_is_32_bit_integer(AST_Binary, function(compressor) {
|
282
|
+
return bitwise_binop.has(this.operator)
|
283
|
+
&& (this.left.is_number(compressor) || this.right.is_number(compressor));
|
214
284
|
});
|
215
285
|
}(function (node, func) {
|
216
286
|
node.DEFMETHOD("is_32_bit_integer", func);
|
@@ -847,30 +917,36 @@ export function is_lhs(node, parent) {
|
|
847
917
|
});
|
848
918
|
|
849
919
|
(function (def_bitwise_negate) {
|
850
|
-
function
|
920
|
+
function basic_bitwise_negation(exp) {
|
851
921
|
return make_node(AST_UnaryPrefix, exp, {
|
852
922
|
operator: "~",
|
853
923
|
expression: exp
|
854
924
|
});
|
855
925
|
}
|
856
926
|
|
857
|
-
def_bitwise_negate(AST_Node, function() {
|
858
|
-
return
|
927
|
+
def_bitwise_negate(AST_Node, function(_compressor) {
|
928
|
+
return basic_bitwise_negation(this);
|
859
929
|
});
|
860
930
|
|
861
|
-
def_bitwise_negate(AST_Number, function() {
|
931
|
+
def_bitwise_negate(AST_Number, function(_compressor) {
|
862
932
|
const neg = ~this.value;
|
863
933
|
if (neg.toString().length > this.value.toString().length) {
|
864
|
-
return
|
934
|
+
return basic_bitwise_negation(this);
|
865
935
|
}
|
866
936
|
return make_node(AST_Number, this, { value: neg });
|
867
937
|
});
|
868
938
|
|
869
|
-
def_bitwise_negate(AST_UnaryPrefix, function(in_32_bit_context) {
|
870
|
-
if (
|
939
|
+
def_bitwise_negate(AST_UnaryPrefix, function(compressor, in_32_bit_context) {
|
940
|
+
if (
|
941
|
+
this.operator == "~"
|
942
|
+
&& (
|
943
|
+
this.expression.is_32_bit_integer(compressor) ||
|
944
|
+
(in_32_bit_context != null ? in_32_bit_context : compressor.in_32_bit_context())
|
945
|
+
)
|
946
|
+
) {
|
871
947
|
return this.expression;
|
872
948
|
} else {
|
873
|
-
return
|
949
|
+
return basic_bitwise_negation(this);
|
874
950
|
}
|
875
951
|
});
|
876
952
|
})(function (node, func) {
|
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.39.
|
7
|
+
"version": "5.39.1",
|
8
8
|
"engines": {
|
9
9
|
"node": ">=10"
|
10
10
|
},
|
@@ -128,7 +128,8 @@
|
|
128
128
|
"no-unused-vars": [
|
129
129
|
"error",
|
130
130
|
{
|
131
|
-
"varsIgnorePattern": "^_"
|
131
|
+
"varsIgnorePattern": "^_",
|
132
|
+
"argsIgnorePattern": "^_"
|
132
133
|
}
|
133
134
|
],
|
134
135
|
"no-tabs": "error",
|