terser 5.17.2 → 5.17.4
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 +10 -0
- package/dist/bundle.min.js +52 -26
- package/lib/compress/drop-side-effect-free.js +9 -0
- package/lib/compress/index.js +17 -21
- package/lib/compress/inference.js +17 -0
- package/lib/output.js +10 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,15 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## v5.17.4
|
4
|
+
|
5
|
+
- Fix crash when trying to negate a class (`!class{}`)
|
6
|
+
- Avoid outputting comments between `yield`/`await` and its argument
|
7
|
+
- Fix detection of left-hand-side of assignment, to avoid optimizing it like any other expression in some edge cases
|
8
|
+
|
9
|
+
## v5.17.3
|
10
|
+
|
11
|
+
- Fix issue with trimming a static class property's contents accessing the class as `this`.
|
12
|
+
|
3
13
|
## v5.17.2
|
4
14
|
- Be less conservative when detecting use-before-definition of `var` in hoisted functions.
|
5
15
|
- Support unusual (but perfectly valid) initializers of for-in and for-of loops.
|
package/dist/bundle.min.js
CHANGED
@@ -9345,14 +9345,17 @@ function OutputStream(options) {
|
|
9345
9345
|
if (!start) return;
|
9346
9346
|
var printed_comments = self.printed_comments;
|
9347
9347
|
|
9348
|
-
// There cannot be a newline between return and its value.
|
9349
|
-
const
|
9348
|
+
// There cannot be a newline between return/yield and its value.
|
9349
|
+
const keyword_with_value =
|
9350
|
+
node instanceof AST_Exit && node.value
|
9351
|
+
|| (node instanceof AST_Await || node instanceof AST_Yield)
|
9352
|
+
&& node.expression;
|
9350
9353
|
|
9351
9354
|
if (
|
9352
9355
|
start.comments_before
|
9353
9356
|
&& printed_comments.has(start.comments_before)
|
9354
9357
|
) {
|
9355
|
-
if (
|
9358
|
+
if (keyword_with_value) {
|
9356
9359
|
start.comments_before = [];
|
9357
9360
|
} else {
|
9358
9361
|
return;
|
@@ -9365,10 +9368,12 @@ function OutputStream(options) {
|
|
9365
9368
|
}
|
9366
9369
|
printed_comments.add(comments);
|
9367
9370
|
|
9368
|
-
if (
|
9371
|
+
if (keyword_with_value) {
|
9369
9372
|
var tw = new TreeWalker(function(node) {
|
9370
9373
|
var parent = tw.parent();
|
9371
9374
|
if (parent instanceof AST_Exit
|
9375
|
+
|| parent instanceof AST_Await
|
9376
|
+
|| parent instanceof AST_Yield
|
9372
9377
|
|| parent instanceof AST_Binary && parent.left === node
|
9373
9378
|
|| parent.TYPE == "Call" && parent.expression === node
|
9374
9379
|
|| parent instanceof AST_Conditional && parent.condition === node
|
@@ -9387,7 +9392,7 @@ function OutputStream(options) {
|
|
9387
9392
|
}
|
9388
9393
|
});
|
9389
9394
|
tw.push(node);
|
9390
|
-
|
9395
|
+
keyword_with_value.walk(tw);
|
9391
9396
|
}
|
9392
9397
|
|
9393
9398
|
if (current_pos == 0) {
|
@@ -14022,6 +14027,9 @@ function is_lhs(node, parent) {
|
|
14022
14027
|
def_negate(AST_Function, function() {
|
14023
14028
|
return basic_negation(this);
|
14024
14029
|
});
|
14030
|
+
def_negate(AST_Class, function() {
|
14031
|
+
return basic_negation(this);
|
14032
|
+
});
|
14025
14033
|
def_negate(AST_Arrow, function() {
|
14026
14034
|
return basic_negation(this);
|
14027
14035
|
});
|
@@ -14155,6 +14163,19 @@ const aborts = (thing) => thing && thing.aborts();
|
|
14155
14163
|
node.DEFMETHOD("aborts", func);
|
14156
14164
|
});
|
14157
14165
|
|
14166
|
+
AST_Node.DEFMETHOD("contains_this", function() {
|
14167
|
+
return walk(this, node => {
|
14168
|
+
if (node instanceof AST_This) return walk_abort;
|
14169
|
+
if (
|
14170
|
+
node !== this
|
14171
|
+
&& node instanceof AST_Scope
|
14172
|
+
&& !(node instanceof AST_Arrow)
|
14173
|
+
) {
|
14174
|
+
return true;
|
14175
|
+
}
|
14176
|
+
});
|
14177
|
+
});
|
14178
|
+
|
14158
14179
|
function is_modified(compressor, tw, node, value, level, immutable) {
|
14159
14180
|
var parent = tw.parent(level);
|
14160
14181
|
var lhs = is_lhs(node, parent);
|
@@ -14760,6 +14781,15 @@ def_drop_side_effect_free(AST_Class, function (compressor) {
|
|
14760
14781
|
}
|
14761
14782
|
}
|
14762
14783
|
|
14784
|
+
if (
|
14785
|
+
prop instanceof AST_ClassProperty
|
14786
|
+
&& prop.static
|
14787
|
+
&& prop.value.has_side_effects(compressor)
|
14788
|
+
&& prop.contains_this()
|
14789
|
+
) {
|
14790
|
+
return this;
|
14791
|
+
}
|
14792
|
+
|
14763
14793
|
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
14764
14794
|
if (trimmed_prop)
|
14765
14795
|
with_effects.push(trimmed_prop);
|
@@ -18313,6 +18343,13 @@ class Compressor extends TreeWalker {
|
|
18313
18343
|
if (opt === node) set_flag(opt, SQUEEZED);
|
18314
18344
|
return opt;
|
18315
18345
|
}
|
18346
|
+
|
18347
|
+
/** Alternative to plain is_lhs() which doesn't work within .optimize() */
|
18348
|
+
is_lhs() {
|
18349
|
+
const self = this.stack[this.stack.length - 1];
|
18350
|
+
const parent = this.stack[this.stack.length - 2];
|
18351
|
+
return is_lhs(self, parent);
|
18352
|
+
}
|
18316
18353
|
}
|
18317
18354
|
|
18318
18355
|
function def_optimize(node, optimizer) {
|
@@ -20470,8 +20507,7 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
20470
20507
|
}
|
20471
20508
|
}
|
20472
20509
|
|
20473
|
-
|
20474
|
-
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
20510
|
+
if (compressor.option("reduce_vars") && !compressor.is_lhs()) {
|
20475
20511
|
return inline_into_symbolref(self, compressor);
|
20476
20512
|
} else {
|
20477
20513
|
return self;
|
@@ -20495,7 +20531,7 @@ def_optimize(AST_Undefined, function(self, compressor) {
|
|
20495
20531
|
return ref;
|
20496
20532
|
}
|
20497
20533
|
}
|
20498
|
-
var lhs =
|
20534
|
+
var lhs = compressor.is_lhs();
|
20499
20535
|
if (lhs && is_atomic(lhs, self)) return self;
|
20500
20536
|
return make_node(AST_UnaryPrefix, self, {
|
20501
20537
|
operator: "void",
|
@@ -20506,7 +20542,7 @@ def_optimize(AST_Undefined, function(self, compressor) {
|
|
20506
20542
|
});
|
20507
20543
|
|
20508
20544
|
def_optimize(AST_Infinity, function(self, compressor) {
|
20509
|
-
var lhs =
|
20545
|
+
var lhs = compressor.is_lhs();
|
20510
20546
|
if (lhs && is_atomic(lhs, self)) return self;
|
20511
20547
|
if (
|
20512
20548
|
compressor.option("keep_infinity")
|
@@ -20527,7 +20563,7 @@ def_optimize(AST_Infinity, function(self, compressor) {
|
|
20527
20563
|
});
|
20528
20564
|
|
20529
20565
|
def_optimize(AST_NaN, function(self, compressor) {
|
20530
|
-
var lhs =
|
20566
|
+
var lhs = compressor.is_lhs();
|
20531
20567
|
if (lhs && !is_atomic(lhs, self)
|
20532
20568
|
|| find_variable(compressor, "NaN")) {
|
20533
20569
|
return make_node(AST_Binary, self, {
|
@@ -21103,7 +21139,10 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
21103
21139
|
}
|
21104
21140
|
}
|
21105
21141
|
}
|
21106
|
-
prop = self.property = best_of_expression(
|
21142
|
+
prop = self.property = best_of_expression(
|
21143
|
+
prop,
|
21144
|
+
make_node_from_constant(key, prop).transform(compressor)
|
21145
|
+
);
|
21107
21146
|
var property = "" + key;
|
21108
21147
|
if (is_basic_identifier_string(property)
|
21109
21148
|
&& property.length <= prop.size() + 1) {
|
@@ -21161,7 +21200,7 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
21161
21200
|
return sym;
|
21162
21201
|
}
|
21163
21202
|
}
|
21164
|
-
if (
|
21203
|
+
if (compressor.is_lhs()) return self;
|
21165
21204
|
if (key !== prop) {
|
21166
21205
|
var sub = self.flatten_object(property, compressor);
|
21167
21206
|
if (sub) {
|
@@ -21229,22 +21268,9 @@ def_optimize(AST_Chain, function (self, compressor) {
|
|
21229
21268
|
return self;
|
21230
21269
|
});
|
21231
21270
|
|
21232
|
-
AST_Lambda.DEFMETHOD("contains_this", function() {
|
21233
|
-
return walk(this, node => {
|
21234
|
-
if (node instanceof AST_This) return walk_abort;
|
21235
|
-
if (
|
21236
|
-
node !== this
|
21237
|
-
&& node instanceof AST_Scope
|
21238
|
-
&& !(node instanceof AST_Arrow)
|
21239
|
-
) {
|
21240
|
-
return true;
|
21241
|
-
}
|
21242
|
-
});
|
21243
|
-
});
|
21244
|
-
|
21245
21271
|
def_optimize(AST_Dot, function(self, compressor) {
|
21246
21272
|
const parent = compressor.parent();
|
21247
|
-
if (is_lhs(
|
21273
|
+
if (compressor.is_lhs()) return self;
|
21248
21274
|
if (compressor.option("unsafe_proto")
|
21249
21275
|
&& self.expression instanceof AST_Dot
|
21250
21276
|
&& self.expression.property == "prototype") {
|
@@ -165,6 +165,15 @@ def_drop_side_effect_free(AST_Class, function (compressor) {
|
|
165
165
|
}
|
166
166
|
}
|
167
167
|
|
168
|
+
if (
|
169
|
+
prop instanceof AST_ClassProperty
|
170
|
+
&& prop.static
|
171
|
+
&& prop.value.has_side_effects(compressor)
|
172
|
+
&& prop.contains_this()
|
173
|
+
) {
|
174
|
+
return this;
|
175
|
+
}
|
176
|
+
|
168
177
|
const trimmed_prop = prop.drop_side_effect_free(compressor);
|
169
178
|
if (trimmed_prop)
|
170
179
|
with_effects.push(trimmed_prop);
|
package/lib/compress/index.js
CHANGED
@@ -442,6 +442,13 @@ class Compressor extends TreeWalker {
|
|
442
442
|
if (opt === node) set_flag(opt, SQUEEZED);
|
443
443
|
return opt;
|
444
444
|
}
|
445
|
+
|
446
|
+
/** Alternative to plain is_lhs() which doesn't work within .optimize() */
|
447
|
+
is_lhs() {
|
448
|
+
const self = this.stack[this.stack.length - 1];
|
449
|
+
const parent = this.stack[this.stack.length - 2];
|
450
|
+
return is_lhs(self, parent);
|
451
|
+
}
|
445
452
|
}
|
446
453
|
|
447
454
|
function def_optimize(node, optimizer) {
|
@@ -2599,8 +2606,7 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
2599
2606
|
}
|
2600
2607
|
}
|
2601
2608
|
|
2602
|
-
|
2603
|
-
if (compressor.option("reduce_vars") && is_lhs(self, parent) !== self) {
|
2609
|
+
if (compressor.option("reduce_vars") && !compressor.is_lhs()) {
|
2604
2610
|
return inline_into_symbolref(self, compressor);
|
2605
2611
|
} else {
|
2606
2612
|
return self;
|
@@ -2624,7 +2630,7 @@ def_optimize(AST_Undefined, function(self, compressor) {
|
|
2624
2630
|
return ref;
|
2625
2631
|
}
|
2626
2632
|
}
|
2627
|
-
var lhs =
|
2633
|
+
var lhs = compressor.is_lhs();
|
2628
2634
|
if (lhs && is_atomic(lhs, self)) return self;
|
2629
2635
|
return make_node(AST_UnaryPrefix, self, {
|
2630
2636
|
operator: "void",
|
@@ -2635,7 +2641,7 @@ def_optimize(AST_Undefined, function(self, compressor) {
|
|
2635
2641
|
});
|
2636
2642
|
|
2637
2643
|
def_optimize(AST_Infinity, function(self, compressor) {
|
2638
|
-
var lhs =
|
2644
|
+
var lhs = compressor.is_lhs();
|
2639
2645
|
if (lhs && is_atomic(lhs, self)) return self;
|
2640
2646
|
if (
|
2641
2647
|
compressor.option("keep_infinity")
|
@@ -2656,7 +2662,7 @@ def_optimize(AST_Infinity, function(self, compressor) {
|
|
2656
2662
|
});
|
2657
2663
|
|
2658
2664
|
def_optimize(AST_NaN, function(self, compressor) {
|
2659
|
-
var lhs =
|
2665
|
+
var lhs = compressor.is_lhs();
|
2660
2666
|
if (lhs && !is_atomic(lhs, self)
|
2661
2667
|
|| find_variable(compressor, "NaN")) {
|
2662
2668
|
return make_node(AST_Binary, self, {
|
@@ -3232,7 +3238,10 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
3232
3238
|
}
|
3233
3239
|
}
|
3234
3240
|
}
|
3235
|
-
prop = self.property = best_of_expression(
|
3241
|
+
prop = self.property = best_of_expression(
|
3242
|
+
prop,
|
3243
|
+
make_node_from_constant(key, prop).transform(compressor)
|
3244
|
+
);
|
3236
3245
|
var property = "" + key;
|
3237
3246
|
if (is_basic_identifier_string(property)
|
3238
3247
|
&& property.length <= prop.size() + 1) {
|
@@ -3290,7 +3299,7 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
3290
3299
|
return sym;
|
3291
3300
|
}
|
3292
3301
|
}
|
3293
|
-
if (
|
3302
|
+
if (compressor.is_lhs()) return self;
|
3294
3303
|
if (key !== prop) {
|
3295
3304
|
var sub = self.flatten_object(property, compressor);
|
3296
3305
|
if (sub) {
|
@@ -3358,22 +3367,9 @@ def_optimize(AST_Chain, function (self, compressor) {
|
|
3358
3367
|
return self;
|
3359
3368
|
});
|
3360
3369
|
|
3361
|
-
AST_Lambda.DEFMETHOD("contains_this", function() {
|
3362
|
-
return walk(this, node => {
|
3363
|
-
if (node instanceof AST_This) return walk_abort;
|
3364
|
-
if (
|
3365
|
-
node !== this
|
3366
|
-
&& node instanceof AST_Scope
|
3367
|
-
&& !(node instanceof AST_Arrow)
|
3368
|
-
) {
|
3369
|
-
return true;
|
3370
|
-
}
|
3371
|
-
});
|
3372
|
-
});
|
3373
|
-
|
3374
3370
|
def_optimize(AST_Dot, function(self, compressor) {
|
3375
3371
|
const parent = compressor.parent();
|
3376
|
-
if (is_lhs(
|
3372
|
+
if (compressor.is_lhs()) return self;
|
3377
3373
|
if (compressor.option("unsafe_proto")
|
3378
3374
|
&& self.expression instanceof AST_Dot
|
3379
3375
|
&& self.expression.property == "prototype") {
|
@@ -84,6 +84,7 @@ import {
|
|
84
84
|
AST_PropAccess,
|
85
85
|
AST_RegExp,
|
86
86
|
AST_Return,
|
87
|
+
AST_Scope,
|
87
88
|
AST_Sequence,
|
88
89
|
AST_SimpleStatement,
|
89
90
|
AST_Statement,
|
@@ -817,6 +818,9 @@ export function is_lhs(node, parent) {
|
|
817
818
|
def_negate(AST_Function, function() {
|
818
819
|
return basic_negation(this);
|
819
820
|
});
|
821
|
+
def_negate(AST_Class, function() {
|
822
|
+
return basic_negation(this);
|
823
|
+
});
|
820
824
|
def_negate(AST_Arrow, function() {
|
821
825
|
return basic_negation(this);
|
822
826
|
});
|
@@ -950,6 +954,19 @@ export const aborts = (thing) => thing && thing.aborts();
|
|
950
954
|
node.DEFMETHOD("aborts", func);
|
951
955
|
});
|
952
956
|
|
957
|
+
AST_Node.DEFMETHOD("contains_this", function() {
|
958
|
+
return walk(this, node => {
|
959
|
+
if (node instanceof AST_This) return walk_abort;
|
960
|
+
if (
|
961
|
+
node !== this
|
962
|
+
&& node instanceof AST_Scope
|
963
|
+
&& !(node instanceof AST_Arrow)
|
964
|
+
) {
|
965
|
+
return true;
|
966
|
+
}
|
967
|
+
});
|
968
|
+
});
|
969
|
+
|
953
970
|
export function is_modified(compressor, tw, node, value, level, immutable) {
|
954
971
|
var parent = tw.parent(level);
|
955
972
|
var lhs = is_lhs(node, parent);
|
package/lib/output.js
CHANGED
@@ -662,14 +662,17 @@ function OutputStream(options) {
|
|
662
662
|
if (!start) return;
|
663
663
|
var printed_comments = self.printed_comments;
|
664
664
|
|
665
|
-
// There cannot be a newline between return and its value.
|
666
|
-
const
|
665
|
+
// There cannot be a newline between return/yield and its value.
|
666
|
+
const keyword_with_value =
|
667
|
+
node instanceof AST_Exit && node.value
|
668
|
+
|| (node instanceof AST_Await || node instanceof AST_Yield)
|
669
|
+
&& node.expression;
|
667
670
|
|
668
671
|
if (
|
669
672
|
start.comments_before
|
670
673
|
&& printed_comments.has(start.comments_before)
|
671
674
|
) {
|
672
|
-
if (
|
675
|
+
if (keyword_with_value) {
|
673
676
|
start.comments_before = [];
|
674
677
|
} else {
|
675
678
|
return;
|
@@ -682,10 +685,12 @@ function OutputStream(options) {
|
|
682
685
|
}
|
683
686
|
printed_comments.add(comments);
|
684
687
|
|
685
|
-
if (
|
688
|
+
if (keyword_with_value) {
|
686
689
|
var tw = new TreeWalker(function(node) {
|
687
690
|
var parent = tw.parent();
|
688
691
|
if (parent instanceof AST_Exit
|
692
|
+
|| parent instanceof AST_Await
|
693
|
+
|| parent instanceof AST_Yield
|
689
694
|
|| parent instanceof AST_Binary && parent.left === node
|
690
695
|
|| parent.TYPE == "Call" && parent.expression === node
|
691
696
|
|| parent instanceof AST_Conditional && parent.condition === node
|
@@ -704,7 +709,7 @@ function OutputStream(options) {
|
|
704
709
|
}
|
705
710
|
});
|
706
711
|
tw.push(node);
|
707
|
-
|
712
|
+
keyword_with_value.walk(tw);
|
708
713
|
}
|
709
714
|
|
710
715
|
if (current_pos == 0) {
|