terser 5.0.0 → 5.3.0
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 +23 -0
- package/LICENSE +1 -1
- package/README.md +2 -6
- package/dist/bundle.min.js +2538 -97
- package/dist/bundle.min.js.map +1 -1
- package/lib/ast.js +28 -4
- package/lib/compress/index.js +179 -66
- package/lib/equivalent-to.js +3 -0
- package/lib/minify.js +5 -1
- package/lib/mozilla-ast.js +40 -3
- package/lib/output.js +18 -3
- package/lib/parse.js +107 -15
- package/lib/size.js +15 -4
- package/package.json +3 -2
- package/tools/domprops.js +2152 -1
- package/tools/terser.d.ts +2 -3
package/lib/ast.js
CHANGED
@@ -527,7 +527,7 @@ var AST_PrefixedTemplateString = DEFNODE("PrefixedTemplateString", "template_str
|
|
527
527
|
$documentation: "A templatestring with a prefix, such as String.raw`foobarbaz`",
|
528
528
|
$propdoc: {
|
529
529
|
template_string: "[AST_TemplateString] The template string",
|
530
|
-
prefix: "[
|
530
|
+
prefix: "[AST_Node] The prefix, which will get called."
|
531
531
|
},
|
532
532
|
_walk: function(visitor) {
|
533
533
|
return visitor._visit(this, function () {
|
@@ -864,6 +864,10 @@ var AST_Import = DEFNODE("Import", "imported_name imported_names module_name", {
|
|
864
864
|
},
|
865
865
|
});
|
866
866
|
|
867
|
+
var AST_ImportMeta = DEFNODE("ImportMeta", null, {
|
868
|
+
$documentation: "A reference to import.meta",
|
869
|
+
});
|
870
|
+
|
867
871
|
var AST_Export = DEFNODE("Export", "exported_definition exported_value is_default exported_names module_name", {
|
868
872
|
$documentation: "An `export` statement",
|
869
873
|
$propdoc: {
|
@@ -904,11 +908,12 @@ var AST_Export = DEFNODE("Export", "exported_definition exported_value is_defaul
|
|
904
908
|
|
905
909
|
/* -----[ OTHER ]----- */
|
906
910
|
|
907
|
-
var AST_Call = DEFNODE("Call", "expression args _annotations", {
|
911
|
+
var AST_Call = DEFNODE("Call", "expression args optional _annotations", {
|
908
912
|
$documentation: "A function call expression",
|
909
913
|
$propdoc: {
|
910
914
|
expression: "[AST_Node] expression to invoke as function",
|
911
915
|
args: "[AST_Node*] array of arguments",
|
916
|
+
optional: "[boolean] whether this is an optional call (IE ?.() )",
|
912
917
|
_annotations: "[number] bitfield containing information about the call"
|
913
918
|
},
|
914
919
|
initialize() {
|
@@ -952,11 +957,13 @@ var AST_Sequence = DEFNODE("Sequence", "expressions", {
|
|
952
957
|
},
|
953
958
|
});
|
954
959
|
|
955
|
-
var AST_PropAccess = DEFNODE("PropAccess", "expression property", {
|
960
|
+
var AST_PropAccess = DEFNODE("PropAccess", "expression property optional", {
|
956
961
|
$documentation: "Base class for property access expressions, i.e. `a.foo` or `a[\"foo\"]`",
|
957
962
|
$propdoc: {
|
958
963
|
expression: "[AST_Node] the “container” expression",
|
959
|
-
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node"
|
964
|
+
property: "[AST_Node|string] the property to access. For AST_Dot this is always a plain string, while for AST_Sub it's an arbitrary AST_Node",
|
965
|
+
|
966
|
+
optional: "[boolean] whether this is an optional property access (IE ?.)"
|
960
967
|
}
|
961
968
|
});
|
962
969
|
|
@@ -989,6 +996,21 @@ var AST_Sub = DEFNODE("Sub", null, {
|
|
989
996
|
},
|
990
997
|
}, AST_PropAccess);
|
991
998
|
|
999
|
+
var AST_Chain = DEFNODE("Chain", "expression", {
|
1000
|
+
$documentation: "A chain expression like a?.b?.(c)?.[d]",
|
1001
|
+
$propdoc: {
|
1002
|
+
expression: "[AST_Call|AST_Dot|AST_Sub] chain element."
|
1003
|
+
},
|
1004
|
+
_walk: function (visitor) {
|
1005
|
+
return visitor._visit(this, function() {
|
1006
|
+
this.expression._walk(visitor);
|
1007
|
+
});
|
1008
|
+
},
|
1009
|
+
_children_backwards(push) {
|
1010
|
+
push(this.expression);
|
1011
|
+
},
|
1012
|
+
});
|
1013
|
+
|
992
1014
|
var AST_Unary = DEFNODE("Unary", "operator expression", {
|
993
1015
|
$documentation: "Base class for unary expressions",
|
994
1016
|
$propdoc: {
|
@@ -1610,6 +1632,7 @@ export {
|
|
1610
1632
|
AST_Call,
|
1611
1633
|
AST_Case,
|
1612
1634
|
AST_Catch,
|
1635
|
+
AST_Chain,
|
1613
1636
|
AST_Class,
|
1614
1637
|
AST_ClassExpression,
|
1615
1638
|
AST_ClassProperty,
|
@@ -1642,6 +1665,7 @@ export {
|
|
1642
1665
|
AST_Hole,
|
1643
1666
|
AST_If,
|
1644
1667
|
AST_Import,
|
1668
|
+
AST_ImportMeta,
|
1645
1669
|
AST_Infinity,
|
1646
1670
|
AST_IterationStatement,
|
1647
1671
|
AST_Jump,
|
package/lib/compress/index.js
CHANGED
@@ -78,6 +78,7 @@ import {
|
|
78
78
|
AST_Call,
|
79
79
|
AST_Case,
|
80
80
|
AST_Catch,
|
81
|
+
AST_Chain,
|
81
82
|
AST_Class,
|
82
83
|
AST_ClassExpression,
|
83
84
|
AST_ClassProperty,
|
@@ -216,7 +217,7 @@ const set_flag = (node, flag) => { node.flags |= flag; };
|
|
216
217
|
const clear_flag = (node, flag) => { node.flags &= ~flag; };
|
217
218
|
|
218
219
|
class Compressor extends TreeWalker {
|
219
|
-
constructor(options, false_by_default) {
|
220
|
+
constructor(options, { false_by_default = false, mangle_options = false }) {
|
220
221
|
super();
|
221
222
|
if (options.defaults !== undefined && !options.defaults) false_by_default = true;
|
222
223
|
this.options = defaults(options, {
|
@@ -274,7 +275,7 @@ class Compressor extends TreeWalker {
|
|
274
275
|
unsafe_regexp : false,
|
275
276
|
unsafe_undefined: false,
|
276
277
|
unused : !false_by_default,
|
277
|
-
warnings : false
|
278
|
+
warnings : false // legacy
|
278
279
|
}, true);
|
279
280
|
var global_defs = this.options["global_defs"];
|
280
281
|
if (typeof global_defs == "object") for (var key in global_defs) {
|
@@ -324,6 +325,7 @@ class Compressor extends TreeWalker {
|
|
324
325
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
325
326
|
this.evaluated_regexps = new Map();
|
326
327
|
this._toplevel = undefined;
|
328
|
+
this.mangle_options = mangle_options;
|
327
329
|
}
|
328
330
|
|
329
331
|
option(key) {
|
@@ -792,13 +794,53 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
792
794
|
pop(tw);
|
793
795
|
return true;
|
794
796
|
});
|
797
|
+
|
798
|
+
def_reduce_vars(AST_Chain, function(tw, descend) {
|
799
|
+
// Chains' conditions apply left-to-right, cumulatively.
|
800
|
+
// If we walk normally we don't go in that order because we would pop before pushing again
|
801
|
+
// Solution: AST_PropAccess and AST_Call push when they are optional, and never pop.
|
802
|
+
// Then we pop everything when they are done being walked.
|
803
|
+
const safe_ids = tw.safe_ids;
|
804
|
+
|
805
|
+
descend();
|
806
|
+
|
807
|
+
// Unroll back to start
|
808
|
+
tw.safe_ids = safe_ids;
|
809
|
+
return true;
|
810
|
+
});
|
811
|
+
def_reduce_vars(AST_Call, function (tw) {
|
812
|
+
// TODO this block should just be { return } but
|
813
|
+
// for some reason the _walk function of AST_Call walks the callee last
|
814
|
+
|
815
|
+
this.expression.walk(tw);
|
816
|
+
|
817
|
+
if (this.optional) {
|
818
|
+
// Never pop -- it's popped at AST_Chain above
|
819
|
+
push(tw);
|
820
|
+
}
|
821
|
+
|
822
|
+
for (const arg of this.args) arg.walk(tw);
|
823
|
+
|
824
|
+
return true;
|
825
|
+
});
|
826
|
+
def_reduce_vars(AST_PropAccess, function (tw) {
|
827
|
+
if (!this.optional) return;
|
828
|
+
|
829
|
+
this.expression.walk(tw);
|
830
|
+
|
831
|
+
// Never pop -- it's popped at AST_Chain above
|
832
|
+
push(tw);
|
833
|
+
|
834
|
+
if (this.property instanceof AST_Node) this.property.walk(tw);
|
835
|
+
|
836
|
+
return true;
|
837
|
+
});
|
795
838
|
def_reduce_vars(AST_Default, function(tw, descend) {
|
796
839
|
push(tw);
|
797
840
|
descend();
|
798
841
|
pop(tw);
|
799
842
|
return true;
|
800
843
|
});
|
801
|
-
|
802
844
|
function mark_lambda(tw, descend, compressor) {
|
803
845
|
clear_flag(this, INLINED);
|
804
846
|
push(tw);
|
@@ -2480,6 +2522,9 @@ function is_undefined(node, compressor) {
|
|
2480
2522
|
if (this.expression instanceof AST_Function && this.property == "prototype") return false;
|
2481
2523
|
return true;
|
2482
2524
|
});
|
2525
|
+
def_may_throw_on_access(AST_Chain, function(compressor) {
|
2526
|
+
return this.expression._dot_throw(compressor);
|
2527
|
+
});
|
2483
2528
|
def_may_throw_on_access(AST_Sequence, function(compressor) {
|
2484
2529
|
return this.tail_node()._dot_throw(compressor);
|
2485
2530
|
});
|
@@ -2630,6 +2675,9 @@ function is_lhs(node, parent) {
|
|
2630
2675
|
}));
|
2631
2676
|
});
|
2632
2677
|
def_find_defs(AST_Node, noop);
|
2678
|
+
def_find_defs(AST_Chain, function(compressor, suffix) {
|
2679
|
+
return this.expression._find_defs(compressor, suffix);
|
2680
|
+
});
|
2633
2681
|
def_find_defs(AST_Dot, function(compressor, suffix) {
|
2634
2682
|
return this.expression._find_defs(compressor, "." + this.property + suffix);
|
2635
2683
|
});
|
@@ -2963,16 +3011,13 @@ var static_fns = convert_to_predicate({
|
|
2963
3011
|
|
2964
3012
|
var fixed = this.fixed_value();
|
2965
3013
|
if (!fixed) return this;
|
2966
|
-
var value;
|
2967
|
-
if (HOP(fixed, "_eval")) {
|
2968
|
-
value = fixed._eval();
|
2969
|
-
} else {
|
2970
|
-
reentrant_ref_eval.add(this);
|
2971
|
-
value = fixed._eval(compressor, depth);
|
2972
|
-
reentrant_ref_eval.delete(this);
|
2973
3014
|
|
2974
|
-
|
2975
|
-
|
3015
|
+
reentrant_ref_eval.add(this);
|
3016
|
+
const value = fixed._eval(compressor, depth);
|
3017
|
+
reentrant_ref_eval.delete(this);
|
3018
|
+
|
3019
|
+
if (value === fixed) return this;
|
3020
|
+
|
2976
3021
|
if (value && typeof value == "object") {
|
2977
3022
|
var escaped = this.definition().escaped;
|
2978
3023
|
if (escaped && depth > escaped) return this;
|
@@ -3000,6 +3045,10 @@ var static_fns = convert_to_predicate({
|
|
3000
3045
|
],
|
3001
3046
|
});
|
3002
3047
|
def_eval(AST_PropAccess, function(compressor, depth) {
|
3048
|
+
if (this.optional) {
|
3049
|
+
const obj = this.expression._eval(compressor, depth);
|
3050
|
+
if (obj == null) return undefined;
|
3051
|
+
}
|
3003
3052
|
if (compressor.option("unsafe")) {
|
3004
3053
|
var key = this.property;
|
3005
3054
|
if (key instanceof AST_Node) {
|
@@ -3041,8 +3090,16 @@ var static_fns = convert_to_predicate({
|
|
3041
3090
|
}
|
3042
3091
|
return this;
|
3043
3092
|
});
|
3093
|
+
def_eval(AST_Chain, function(compressor, depth) {
|
3094
|
+
const evaluated = this.expression._eval(compressor, depth);
|
3095
|
+
return evaluated === this.expression ? this : evaluated;
|
3096
|
+
});
|
3044
3097
|
def_eval(AST_Call, function(compressor, depth) {
|
3045
3098
|
var exp = this.expression;
|
3099
|
+
if (this.optional) {
|
3100
|
+
const callee = this.expression._eval(compressor, depth);
|
3101
|
+
if (callee == null) return undefined;
|
3102
|
+
}
|
3046
3103
|
if (compressor.option("unsafe") && exp instanceof AST_PropAccess) {
|
3047
3104
|
var key = exp.property;
|
3048
3105
|
if (key instanceof AST_Node) {
|
@@ -3244,9 +3301,11 @@ const pure_prop_access_globals = new Set([
|
|
3244
3301
|
return any(this.body, compressor);
|
3245
3302
|
});
|
3246
3303
|
def_has_side_effects(AST_Call, function(compressor) {
|
3247
|
-
if (
|
3304
|
+
if (
|
3305
|
+
!this.is_expr_pure(compressor)
|
3248
3306
|
&& (!this.expression.is_call_pure(compressor)
|
3249
|
-
|| this.expression.has_side_effects(compressor))
|
3307
|
+
|| this.expression.has_side_effects(compressor))
|
3308
|
+
) {
|
3250
3309
|
return true;
|
3251
3310
|
}
|
3252
3311
|
return any(this.args, compressor);
|
@@ -3329,14 +3388,21 @@ const pure_prop_access_globals = new Set([
|
|
3329
3388
|
return any(this.elements, compressor);
|
3330
3389
|
});
|
3331
3390
|
def_has_side_effects(AST_Dot, function(compressor) {
|
3332
|
-
return this.expression.may_throw_on_access(compressor)
|
3391
|
+
return !this.optional && this.expression.may_throw_on_access(compressor)
|
3333
3392
|
|| this.expression.has_side_effects(compressor);
|
3334
3393
|
});
|
3335
3394
|
def_has_side_effects(AST_Sub, function(compressor) {
|
3336
|
-
|
3395
|
+
if (this.optional && is_nullish(this.expression)) {
|
3396
|
+
return false;
|
3397
|
+
}
|
3398
|
+
|
3399
|
+
return !this.optional && this.expression.may_throw_on_access(compressor)
|
3337
3400
|
|| this.expression.has_side_effects(compressor)
|
3338
3401
|
|| this.property.has_side_effects(compressor);
|
3339
3402
|
});
|
3403
|
+
def_has_side_effects(AST_Chain, function (compressor) {
|
3404
|
+
return this.expression.has_side_effects(compressor);
|
3405
|
+
});
|
3340
3406
|
def_has_side_effects(AST_Sequence, function(compressor) {
|
3341
3407
|
return any(this.expressions, compressor);
|
3342
3408
|
});
|
@@ -3396,6 +3462,7 @@ const pure_prop_access_globals = new Set([
|
|
3396
3462
|
return any(this.body, compressor);
|
3397
3463
|
});
|
3398
3464
|
def_may_throw(AST_Call, function(compressor) {
|
3465
|
+
if (this.optional && is_nullish(this.expression)) return false;
|
3399
3466
|
if (any(this.args, compressor)) return true;
|
3400
3467
|
if (this.is_expr_pure(compressor)) return false;
|
3401
3468
|
if (this.expression.may_throw(compressor)) return true;
|
@@ -3414,10 +3481,6 @@ const pure_prop_access_globals = new Set([
|
|
3414
3481
|
def_may_throw(AST_Definitions, function(compressor) {
|
3415
3482
|
return any(this.definitions, compressor);
|
3416
3483
|
});
|
3417
|
-
def_may_throw(AST_Dot, function(compressor) {
|
3418
|
-
return this.expression.may_throw_on_access(compressor)
|
3419
|
-
|| this.expression.may_throw(compressor);
|
3420
|
-
});
|
3421
3484
|
def_may_throw(AST_If, function(compressor) {
|
3422
3485
|
return this.condition.may_throw(compressor)
|
3423
3486
|
|| this.body && this.body.may_throw(compressor)
|
@@ -3457,11 +3520,20 @@ const pure_prop_access_globals = new Set([
|
|
3457
3520
|
def_may_throw(AST_SimpleStatement, function(compressor) {
|
3458
3521
|
return this.body.may_throw(compressor);
|
3459
3522
|
});
|
3523
|
+
def_may_throw(AST_Dot, function(compressor) {
|
3524
|
+
return !this.optional && this.expression.may_throw_on_access(compressor)
|
3525
|
+
|| this.expression.may_throw(compressor);
|
3526
|
+
});
|
3460
3527
|
def_may_throw(AST_Sub, function(compressor) {
|
3461
|
-
|
3528
|
+
if (this.optional && is_nullish(this.expression)) return false;
|
3529
|
+
|
3530
|
+
return !this.optional && this.expression.may_throw_on_access(compressor)
|
3462
3531
|
|| this.expression.may_throw(compressor)
|
3463
3532
|
|| this.property.may_throw(compressor);
|
3464
3533
|
});
|
3534
|
+
def_may_throw(AST_Chain, function(compressor) {
|
3535
|
+
return this.expression.may_throw(compressor);
|
3536
|
+
});
|
3465
3537
|
def_may_throw(AST_Switch, function(compressor) {
|
3466
3538
|
return this.expression.may_throw(compressor)
|
3467
3539
|
|| any(this.body, compressor);
|
@@ -3619,9 +3691,9 @@ def_optimize(AST_Block, function(self, compressor) {
|
|
3619
3691
|
|
3620
3692
|
function can_be_extracted_from_if_block(node) {
|
3621
3693
|
return !(
|
3622
|
-
node instanceof AST_Const
|
3623
|
-
node instanceof AST_Let
|
3624
|
-
node instanceof AST_Class
|
3694
|
+
node instanceof AST_Const
|
3695
|
+
|| node instanceof AST_Let
|
3696
|
+
|| node instanceof AST_Class
|
3625
3697
|
);
|
3626
3698
|
}
|
3627
3699
|
|
@@ -4188,7 +4260,9 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
4188
4260
|
&& !top_retain(def)
|
4189
4261
|
&& (value = sym.fixed_value()) === node.value
|
4190
4262
|
&& value instanceof AST_Object
|
4191
|
-
&& !value.properties.some(prop =>
|
4263
|
+
&& !value.properties.some(prop =>
|
4264
|
+
prop instanceof AST_Expansion || prop.computed_key()
|
4265
|
+
)
|
4192
4266
|
) {
|
4193
4267
|
descend(node, this);
|
4194
4268
|
const defs = new Map();
|
@@ -4255,6 +4329,10 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
4255
4329
|
def_drop_side_effect_free(AST_Constant, return_null);
|
4256
4330
|
def_drop_side_effect_free(AST_This, return_null);
|
4257
4331
|
def_drop_side_effect_free(AST_Call, function(compressor, first_in_statement) {
|
4332
|
+
if (this.optional && is_nullish(this.expression)) {
|
4333
|
+
return make_node(AST_Undefined, this);
|
4334
|
+
}
|
4335
|
+
|
4258
4336
|
if (!this.is_expr_pure(compressor)) {
|
4259
4337
|
if (this.expression.is_call_pure(compressor)) {
|
4260
4338
|
var exprs = this.args.slice();
|
@@ -4395,17 +4473,28 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
4395
4473
|
return values && make_sequence(this, values);
|
4396
4474
|
});
|
4397
4475
|
def_drop_side_effect_free(AST_Dot, function(compressor, first_in_statement) {
|
4476
|
+
if (this.optional) {
|
4477
|
+
return is_nullish(this.expression) ? make_node(AST_Undefined, this) : this;
|
4478
|
+
}
|
4398
4479
|
if (this.expression.may_throw_on_access(compressor)) return this;
|
4480
|
+
|
4399
4481
|
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
4400
4482
|
});
|
4401
4483
|
def_drop_side_effect_free(AST_Sub, function(compressor, first_in_statement) {
|
4484
|
+
if (this.optional) {
|
4485
|
+
return is_nullish(this.expression) ? make_node(AST_Undefined, this): this;
|
4486
|
+
}
|
4402
4487
|
if (this.expression.may_throw_on_access(compressor)) return this;
|
4488
|
+
|
4403
4489
|
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
|
4404
4490
|
if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
|
4405
4491
|
var property = this.property.drop_side_effect_free(compressor);
|
4406
4492
|
if (!property) return expression;
|
4407
4493
|
return make_sequence(this, [ expression, property ]);
|
4408
4494
|
});
|
4495
|
+
def_drop_side_effect_free(AST_Chain, function (compressor, first_in_statement) {
|
4496
|
+
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
4497
|
+
});
|
4409
4498
|
def_drop_side_effect_free(AST_Sequence, function(compressor) {
|
4410
4499
|
var last = this.tail_node();
|
4411
4500
|
var expr = last.drop_side_effect_free(compressor);
|
@@ -4946,6 +5035,10 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
4946
5035
|
}
|
4947
5036
|
}
|
4948
5037
|
|
5038
|
+
if (self.optional && is_nullish(fn)) {
|
5039
|
+
return make_node(AST_Undefined, self);
|
5040
|
+
}
|
5041
|
+
|
4949
5042
|
var is_func = fn instanceof AST_Lambda;
|
4950
5043
|
|
4951
5044
|
if (is_func && fn.pinned()) return self;
|
@@ -5157,6 +5250,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
5157
5250
|
return make_node(AST_Call, self, {
|
5158
5251
|
expression: make_node(AST_Dot, exp, {
|
5159
5252
|
expression: exp.expression,
|
5253
|
+
optional: false,
|
5160
5254
|
property: "call"
|
5161
5255
|
}),
|
5162
5256
|
args: args
|
@@ -5203,7 +5297,9 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
5203
5297
|
var ast = parse(code);
|
5204
5298
|
var mangle = { ie8: compressor.option("ie8") };
|
5205
5299
|
ast.figure_out_scope(mangle);
|
5206
|
-
var comp = new Compressor(compressor.options
|
5300
|
+
var comp = new Compressor(compressor.options, {
|
5301
|
+
mangle_options: compressor.mangle_options
|
5302
|
+
});
|
5207
5303
|
ast = ast.transform(comp);
|
5208
5304
|
ast.figure_out_scope(mangle);
|
5209
5305
|
base54.reset();
|
@@ -6285,7 +6381,8 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
6285
6381
|
let single_use = def.single_use
|
6286
6382
|
&& !(parent instanceof AST_Call
|
6287
6383
|
&& (parent.is_expr_pure(compressor))
|
6288
|
-
|| has_annotation(parent, _NOINLINE))
|
6384
|
+
|| has_annotation(parent, _NOINLINE))
|
6385
|
+
&& !(fixed instanceof AST_Defun && parent instanceof AST_Export);
|
6289
6386
|
|
6290
6387
|
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
6291
6388
|
if (retain_top_func(fixed, compressor)) {
|
@@ -6386,8 +6483,8 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
6386
6483
|
}
|
6387
6484
|
|
6388
6485
|
if (replace) {
|
6389
|
-
const name_length =
|
6390
|
-
const replace_size = replace.size();
|
6486
|
+
const name_length = self.size(compressor);
|
6487
|
+
const replace_size = replace.size(compressor);
|
6391
6488
|
|
6392
6489
|
let overhead = 0;
|
6393
6490
|
if (compressor.option("unused") && !compressor.exposed(def)) {
|
@@ -6592,6 +6689,10 @@ function is_nullish(node) {
|
|
6592
6689
|
&& (fixed = node.definition().fixed) instanceof AST_Node
|
6593
6690
|
&& is_nullish(fixed)
|
6594
6691
|
)
|
6692
|
+
// Recurse into those optional chains!
|
6693
|
+
|| node instanceof AST_PropAccess && node.optional && is_nullish(node.expression)
|
6694
|
+
|| node instanceof AST_Call && node.optional && is_nullish(node.expression)
|
6695
|
+
|| node instanceof AST_Chain && is_nullish(node.expression)
|
6595
6696
|
);
|
6596
6697
|
}
|
6597
6698
|
|
@@ -6974,6 +7075,41 @@ function safe_to_flatten(value, compressor) {
|
|
6974
7075
|
return compressor.parent() instanceof AST_New;
|
6975
7076
|
}
|
6976
7077
|
|
7078
|
+
AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) {
|
7079
|
+
if (!compressor.option("properties")) return;
|
7080
|
+
var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015;
|
7081
|
+
var expr = this.expression;
|
7082
|
+
if (expr instanceof AST_Object) {
|
7083
|
+
var props = expr.properties;
|
7084
|
+
for (var i = props.length; --i >= 0;) {
|
7085
|
+
var prop = props[i];
|
7086
|
+
if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) {
|
7087
|
+
if (!props.every((prop) => {
|
7088
|
+
return prop instanceof AST_ObjectKeyVal
|
7089
|
+
|| arrows && prop instanceof AST_ConciseMethod && !prop.is_generator;
|
7090
|
+
})) break;
|
7091
|
+
if (!safe_to_flatten(prop.value, compressor)) break;
|
7092
|
+
return make_node(AST_Sub, this, {
|
7093
|
+
expression: make_node(AST_Array, expr, {
|
7094
|
+
elements: props.map(function(prop) {
|
7095
|
+
var v = prop.value;
|
7096
|
+
if (v instanceof AST_Accessor) v = make_node(AST_Function, v, v);
|
7097
|
+
var k = prop.key;
|
7098
|
+
if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) {
|
7099
|
+
return make_sequence(prop, [ k, v ]);
|
7100
|
+
}
|
7101
|
+
return v;
|
7102
|
+
})
|
7103
|
+
}),
|
7104
|
+
property: make_node(AST_Number, this, {
|
7105
|
+
value: i
|
7106
|
+
})
|
7107
|
+
});
|
7108
|
+
}
|
7109
|
+
}
|
7110
|
+
}
|
7111
|
+
});
|
7112
|
+
|
6977
7113
|
def_optimize(AST_Sub, function(self, compressor) {
|
6978
7114
|
var expr = self.expression;
|
6979
7115
|
var prop = self.property;
|
@@ -6996,6 +7132,7 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
6996
7132
|
&& property.length <= prop.size() + 1) {
|
6997
7133
|
return make_node(AST_Dot, self, {
|
6998
7134
|
expression: expr,
|
7135
|
+
optional: self.optional,
|
6999
7136
|
property: property,
|
7000
7137
|
quote: prop.quote,
|
7001
7138
|
}).optimize(compressor);
|
@@ -7098,6 +7235,14 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
7098
7235
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
7099
7236
|
return best_of(compressor, ev, self);
|
7100
7237
|
}
|
7238
|
+
if (self.optional && is_nullish(self.expression)) {
|
7239
|
+
return make_node(AST_Undefined, self);
|
7240
|
+
}
|
7241
|
+
return self;
|
7242
|
+
});
|
7243
|
+
|
7244
|
+
def_optimize(AST_Chain, function (self, compressor) {
|
7245
|
+
self.expression = self.expression.optimize(compressor);
|
7101
7246
|
return self;
|
7102
7247
|
});
|
7103
7248
|
|
@@ -7114,41 +7259,6 @@ AST_Lambda.DEFMETHOD("contains_this", function() {
|
|
7114
7259
|
});
|
7115
7260
|
});
|
7116
7261
|
|
7117
|
-
AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) {
|
7118
|
-
if (!compressor.option("properties")) return;
|
7119
|
-
var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015;
|
7120
|
-
var expr = this.expression;
|
7121
|
-
if (expr instanceof AST_Object) {
|
7122
|
-
var props = expr.properties;
|
7123
|
-
for (var i = props.length; --i >= 0;) {
|
7124
|
-
var prop = props[i];
|
7125
|
-
if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) {
|
7126
|
-
if (!props.every((prop) => {
|
7127
|
-
return prop instanceof AST_ObjectKeyVal
|
7128
|
-
|| arrows && prop instanceof AST_ConciseMethod && !prop.is_generator;
|
7129
|
-
})) break;
|
7130
|
-
if (!safe_to_flatten(prop.value, compressor)) break;
|
7131
|
-
return make_node(AST_Sub, this, {
|
7132
|
-
expression: make_node(AST_Array, expr, {
|
7133
|
-
elements: props.map(function(prop) {
|
7134
|
-
var v = prop.value;
|
7135
|
-
if (v instanceof AST_Accessor) v = make_node(AST_Function, v, v);
|
7136
|
-
var k = prop.key;
|
7137
|
-
if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) {
|
7138
|
-
return make_sequence(prop, [ k, v ]);
|
7139
|
-
}
|
7140
|
-
return v;
|
7141
|
-
})
|
7142
|
-
}),
|
7143
|
-
property: make_node(AST_Number, this, {
|
7144
|
-
value: i
|
7145
|
-
})
|
7146
|
-
});
|
7147
|
-
}
|
7148
|
-
}
|
7149
|
-
}
|
7150
|
-
});
|
7151
|
-
|
7152
7262
|
def_optimize(AST_Dot, function(self, compressor) {
|
7153
7263
|
const parent = compressor.parent();
|
7154
7264
|
if (is_lhs(self, parent)) return self;
|
@@ -7199,6 +7309,9 @@ def_optimize(AST_Dot, function(self, compressor) {
|
|
7199
7309
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
7200
7310
|
return best_of(compressor, ev, self);
|
7201
7311
|
}
|
7312
|
+
if (self.optional && is_nullish(self.expression)) {
|
7313
|
+
return make_node(AST_Undefined, self);
|
7314
|
+
}
|
7202
7315
|
return self;
|
7203
7316
|
});
|
7204
7317
|
|
@@ -7282,10 +7395,10 @@ def_optimize(AST_Function, function(self, compressor) {
|
|
7282
7395
|
&& !self.is_generator
|
7283
7396
|
&& !self.uses_arguments
|
7284
7397
|
&& !self.pinned()) {
|
7285
|
-
const
|
7398
|
+
const uses_this = walk(self, node => {
|
7286
7399
|
if (node instanceof AST_This) return walk_abort;
|
7287
7400
|
});
|
7288
|
-
if (!
|
7401
|
+
if (!uses_this) return make_node(AST_Arrow, self, self).optimize(compressor);
|
7289
7402
|
}
|
7290
7403
|
return self;
|
7291
7404
|
});
|
package/lib/equivalent-to.js
CHANGED
@@ -26,6 +26,7 @@ import {
|
|
26
26
|
AST_ForOf,
|
27
27
|
AST_If,
|
28
28
|
AST_Import,
|
29
|
+
AST_ImportMeta,
|
29
30
|
AST_Jump,
|
30
31
|
AST_LabeledStatement,
|
31
32
|
AST_Lambda,
|
@@ -209,6 +210,8 @@ AST_Import.prototype.shallow_cmp = mkshallow({
|
|
209
210
|
imported_names: "exist"
|
210
211
|
});
|
211
212
|
|
213
|
+
AST_ImportMeta.prototype.shallow_cmp = pass_through;
|
214
|
+
|
212
215
|
AST_Export.prototype.shallow_cmp = mkshallow({
|
213
216
|
exported_definition: "exist",
|
214
217
|
exported_value: "exist",
|
package/lib/minify.js
CHANGED
@@ -181,7 +181,11 @@ async function minify(files, options) {
|
|
181
181
|
toplevel.expand_names(options.mangle);
|
182
182
|
}
|
183
183
|
if (timings) timings.compress = Date.now();
|
184
|
-
if (options.compress)
|
184
|
+
if (options.compress) {
|
185
|
+
toplevel = new Compressor(options.compress, {
|
186
|
+
mangle_options: options.mangle
|
187
|
+
}).compress(toplevel);
|
188
|
+
}
|
185
189
|
if (timings) timings.scope = Date.now();
|
186
190
|
if (options.mangle) toplevel.figure_out_scope(options.mangle);
|
187
191
|
if (timings) timings.mangle = Date.now();
|
package/lib/mozilla-ast.js
CHANGED
@@ -59,6 +59,7 @@ import {
|
|
59
59
|
AST_Call,
|
60
60
|
AST_Case,
|
61
61
|
AST_Catch,
|
62
|
+
AST_Chain,
|
62
63
|
AST_Class,
|
63
64
|
AST_ClassExpression,
|
64
65
|
AST_ClassProperty,
|
@@ -89,6 +90,7 @@ import {
|
|
89
90
|
AST_Hole,
|
90
91
|
AST_If,
|
91
92
|
AST_Import,
|
93
|
+
AST_ImportMeta,
|
92
94
|
AST_Label,
|
93
95
|
AST_LabeledStatement,
|
94
96
|
AST_LabelRef,
|
@@ -418,7 +420,15 @@ import {
|
|
418
420
|
start : my_start_token(M),
|
419
421
|
end : my_end_token(M),
|
420
422
|
property : M.computed ? from_moz(M.property) : M.property.name,
|
421
|
-
expression : from_moz(M.object)
|
423
|
+
expression : from_moz(M.object),
|
424
|
+
optional : M.optional || false
|
425
|
+
});
|
426
|
+
},
|
427
|
+
ChainExpression: function(M) {
|
428
|
+
return new AST_Chain({
|
429
|
+
start : my_start_token(M),
|
430
|
+
end : my_end_token(M),
|
431
|
+
expression : from_moz(M.expression)
|
422
432
|
});
|
423
433
|
},
|
424
434
|
SwitchCase: function(M) {
|
@@ -545,6 +555,11 @@ import {
|
|
545
555
|
start: my_start_token(M),
|
546
556
|
end: my_end_token(M)
|
547
557
|
});
|
558
|
+
} else if (M.meta.name === "import" && M.property.name === "meta") {
|
559
|
+
return new AST_ImportMeta({
|
560
|
+
start: my_start_token(M),
|
561
|
+
end: my_end_token(M)
|
562
|
+
});
|
548
563
|
}
|
549
564
|
},
|
550
565
|
Identifier: function(M) {
|
@@ -629,7 +644,7 @@ import {
|
|
629
644
|
map("AssignmentExpression", AST_Assign, "operator=operator, left>left, right>right");
|
630
645
|
map("ConditionalExpression", AST_Conditional, "test>condition, consequent>consequent, alternate>alternative");
|
631
646
|
map("NewExpression", AST_New, "callee>expression, arguments@args");
|
632
|
-
map("CallExpression", AST_Call, "callee>expression, arguments@args");
|
647
|
+
map("CallExpression", AST_Call, "callee>expression, optional=optional, arguments@args");
|
633
648
|
|
634
649
|
def_to_moz(AST_Toplevel, function To_Moz_Program(M) {
|
635
650
|
return to_moz_scope("Program", M);
|
@@ -836,6 +851,20 @@ import {
|
|
836
851
|
};
|
837
852
|
});
|
838
853
|
|
854
|
+
def_to_moz(AST_ImportMeta, function To_Moz_MetaProperty() {
|
855
|
+
return {
|
856
|
+
type: "MetaProperty",
|
857
|
+
meta: {
|
858
|
+
type: "Identifier",
|
859
|
+
name: "import"
|
860
|
+
},
|
861
|
+
property: {
|
862
|
+
type: "Identifier",
|
863
|
+
name: "meta"
|
864
|
+
}
|
865
|
+
};
|
866
|
+
});
|
867
|
+
|
839
868
|
def_to_moz(AST_Sequence, function To_Moz_SequenceExpression(M) {
|
840
869
|
return {
|
841
870
|
type: "SequenceExpression",
|
@@ -849,7 +878,15 @@ import {
|
|
849
878
|
type: "MemberExpression",
|
850
879
|
object: to_moz(M.expression),
|
851
880
|
computed: isComputed,
|
852
|
-
property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property}
|
881
|
+
property: isComputed ? to_moz(M.property) : {type: "Identifier", name: M.property},
|
882
|
+
optional: M.optional
|
883
|
+
};
|
884
|
+
});
|
885
|
+
|
886
|
+
def_to_moz(AST_Chain, function To_Moz_ChainExpression(M) {
|
887
|
+
return {
|
888
|
+
type: "ChainExpression",
|
889
|
+
expression: to_moz(M.expression)
|
853
890
|
};
|
854
891
|
});
|
855
892
|
|