terser 5.6.0-beta → 5.7.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 +35 -0
- package/README.md +25 -19
- package/dist/bundle.min.js +250 -169
- package/lib/ast.js +15 -4
- package/lib/cli.js +0 -2
- package/lib/compress/index.js +102 -64
- package/lib/equivalent-to.js +5 -0
- package/lib/minify.js +26 -9
- package/lib/output.js +8 -1
- package/lib/parse.js +72 -80
- package/lib/scope.js +8 -3
- package/lib/size.js +9 -2
- package/lib/utils/index.js +6 -6
- package/package.json +4 -3
- package/tools/domprops.js +1 -0
package/dist/bundle.min.js
CHANGED
@@ -72,10 +72,8 @@ class DefaultsError extends Error {
|
|
72
72
|
function defaults(args, defs, croak) {
|
73
73
|
if (args === true) {
|
74
74
|
args = {};
|
75
|
-
}
|
76
|
-
|
77
|
-
if (args != null && typeof args === "object") {
|
78
|
-
args = Object.assign({}, args);
|
75
|
+
} else if (args != null && typeof args === "object") {
|
76
|
+
args = {...args};
|
79
77
|
}
|
80
78
|
|
81
79
|
const ret = args || {};
|
@@ -204,7 +202,7 @@ function mergeSort(array, cmp) {
|
|
204
202
|
function makePredicate(words) {
|
205
203
|
if (!Array.isArray(words)) words = words.split(" ");
|
206
204
|
|
207
|
-
return new Set(words);
|
205
|
+
return new Set(words.sort());
|
208
206
|
}
|
209
207
|
|
210
208
|
function map_add(map, key, value) {
|
@@ -243,6 +241,7 @@ function keep_name(keep_setting, name) {
|
|
243
241
|
}
|
244
242
|
|
245
243
|
var lineTerminatorEscape = {
|
244
|
+
"\0": "0",
|
246
245
|
"\n": "n",
|
247
246
|
"\r": "r",
|
248
247
|
"\u2028": "u2028",
|
@@ -250,7 +249,8 @@ var lineTerminatorEscape = {
|
|
250
249
|
};
|
251
250
|
function regexp_source_fix(source) {
|
252
251
|
// V8 does not escape line terminators in regexp patterns in node 12
|
253
|
-
|
252
|
+
// We'll also remove literal \0
|
253
|
+
return source.replace(/[\0\n\r\u2028\u2029]/g, function (match, offset) {
|
254
254
|
var escaped = source[offset - 1] == "\\"
|
255
255
|
&& (source[offset - 2] != "\\"
|
256
256
|
|| /(?:^|[^\\])(?:\\{2})*$/.test(source.slice(0, offset - 1)));
|
@@ -1457,7 +1457,7 @@ function parse($TEXT, options) {
|
|
1457
1457
|
if (is_if_body) {
|
1458
1458
|
croak("classes are not allowed as the body of an if");
|
1459
1459
|
}
|
1460
|
-
return class_(AST_DefClass);
|
1460
|
+
return class_(AST_DefClass, is_export_default);
|
1461
1461
|
|
1462
1462
|
case "function":
|
1463
1463
|
next();
|
@@ -2652,7 +2652,7 @@ function parse($TEXT, options) {
|
|
2652
2652
|
return new AST_Object({ properties: a });
|
2653
2653
|
});
|
2654
2654
|
|
2655
|
-
function class_(KindOfClass) {
|
2655
|
+
function class_(KindOfClass, is_export_default) {
|
2656
2656
|
var start, method, class_name, extends_, a = [];
|
2657
2657
|
|
2658
2658
|
S.input.push_directives_stack(); // Push directive stack, but not scope stack
|
@@ -2663,7 +2663,11 @@ function parse($TEXT, options) {
|
|
2663
2663
|
}
|
2664
2664
|
|
2665
2665
|
if (KindOfClass === AST_DefClass && !class_name) {
|
2666
|
-
|
2666
|
+
if (is_export_default) {
|
2667
|
+
KindOfClass = AST_ClassExpression;
|
2668
|
+
} else {
|
2669
|
+
unexpected();
|
2670
|
+
}
|
2667
2671
|
}
|
2668
2672
|
|
2669
2673
|
if (S.token.value == "extends") {
|
@@ -2696,9 +2700,9 @@ function parse($TEXT, options) {
|
|
2696
2700
|
}
|
2697
2701
|
|
2698
2702
|
function concise_method_or_getset(name, start, is_class) {
|
2699
|
-
|
2703
|
+
const get_symbol_ast = (name, SymbolClass = AST_SymbolMethod) => {
|
2700
2704
|
if (typeof name === "string" || typeof name === "number") {
|
2701
|
-
return new
|
2705
|
+
return new SymbolClass({
|
2702
2706
|
start,
|
2703
2707
|
name: "" + name,
|
2704
2708
|
end: prev()
|
@@ -2708,47 +2712,71 @@ function parse($TEXT, options) {
|
|
2708
2712
|
}
|
2709
2713
|
return name;
|
2710
2714
|
};
|
2711
|
-
|
2712
|
-
|
2713
|
-
|
2714
|
-
|
2715
|
-
end: property_token,
|
2716
|
-
name: "" + name
|
2717
|
-
});
|
2718
|
-
} else if (name === null) {
|
2719
|
-
unexpected();
|
2720
|
-
}
|
2721
|
-
return name;
|
2722
|
-
};
|
2723
|
-
var privatename = start.type == "privatename";
|
2715
|
+
|
2716
|
+
const is_not_method_start = () =>
|
2717
|
+
!is("punc", "(") && !is("punc", ",") && !is("punc", "}") && !is("operator", "=");
|
2718
|
+
|
2724
2719
|
var is_async = false;
|
2725
2720
|
var is_static = false;
|
2726
2721
|
var is_generator = false;
|
2727
|
-
var
|
2728
|
-
|
2722
|
+
var is_private = false;
|
2723
|
+
var accessor_type = null;
|
2724
|
+
|
2725
|
+
if (is_class && name === "static" && is_not_method_start()) {
|
2729
2726
|
is_static = true;
|
2730
|
-
property_token = S.token;
|
2731
|
-
privatename = property_token.type == "privatename";
|
2732
2727
|
name = as_property_name();
|
2733
2728
|
}
|
2734
|
-
if (name === "async" &&
|
2729
|
+
if (name === "async" && is_not_method_start()) {
|
2735
2730
|
is_async = true;
|
2736
|
-
property_token = S.token;
|
2737
|
-
privatename = property_token.type == "privatename";
|
2738
2731
|
name = as_property_name();
|
2739
2732
|
}
|
2740
|
-
if (
|
2733
|
+
if (prev().type === "operator" && prev().value === "*") {
|
2741
2734
|
is_generator = true;
|
2742
|
-
property_token = S.token;
|
2743
|
-
privatename = property_token.type == "privatename";
|
2744
2735
|
name = as_property_name();
|
2745
|
-
|
2746
|
-
|
2736
|
+
}
|
2737
|
+
if ((name === "get" || name === "set") && is_not_method_start()) {
|
2738
|
+
accessor_type = name;
|
2739
|
+
name = as_property_name();
|
2740
|
+
}
|
2741
|
+
if (prev().type === "privatename") {
|
2742
|
+
is_private = true;
|
2743
|
+
}
|
2744
|
+
|
2745
|
+
const property_token = prev();
|
2746
|
+
|
2747
|
+
if (accessor_type != null) {
|
2748
|
+
if (!is_private) {
|
2749
|
+
const AccessorClass = accessor_type === "get"
|
2750
|
+
? AST_ObjectGetter
|
2751
|
+
: AST_ObjectSetter;
|
2752
|
+
|
2753
|
+
name = get_symbol_ast(name);
|
2754
|
+
return new AccessorClass({
|
2755
|
+
start,
|
2756
|
+
static: is_static,
|
2757
|
+
key: name,
|
2758
|
+
quote: name instanceof AST_SymbolMethod ? property_token.quote : undefined,
|
2759
|
+
value: create_accessor(),
|
2760
|
+
end: prev()
|
2761
|
+
});
|
2762
|
+
} else {
|
2763
|
+
const AccessorClass = accessor_type === "get"
|
2764
|
+
? AST_PrivateGetter
|
2765
|
+
: AST_PrivateSetter;
|
2766
|
+
|
2767
|
+
return new AccessorClass({
|
2768
|
+
start,
|
2769
|
+
static: is_static,
|
2770
|
+
key: get_symbol_ast(name),
|
2771
|
+
value: create_accessor(),
|
2772
|
+
end: prev(),
|
2773
|
+
});
|
2747
2774
|
}
|
2748
2775
|
}
|
2776
|
+
|
2749
2777
|
if (is("punc", "(")) {
|
2750
|
-
name =
|
2751
|
-
const AST_MethodVariant =
|
2778
|
+
name = get_symbol_ast(name);
|
2779
|
+
const AST_MethodVariant = is_private
|
2752
2780
|
? AST_PrivateMethod
|
2753
2781
|
: AST_ConciseMethod;
|
2754
2782
|
var node = new AST_MethodVariant({
|
@@ -2764,57 +2792,13 @@ function parse($TEXT, options) {
|
|
2764
2792
|
});
|
2765
2793
|
return node;
|
2766
2794
|
}
|
2767
|
-
const setter_token = S.token;
|
2768
|
-
if ((name === "get" || name === "set") && setter_token.type === "privatename") {
|
2769
|
-
next();
|
2770
|
-
|
2771
|
-
const AST_AccessorVariant =
|
2772
|
-
name === "get"
|
2773
|
-
? AST_PrivateGetter
|
2774
|
-
: AST_PrivateSetter;
|
2775
|
-
|
2776
|
-
return new AST_AccessorVariant({
|
2777
|
-
start,
|
2778
|
-
static: is_static,
|
2779
|
-
key: get_method_name_ast(setter_token.value, start),
|
2780
|
-
value: create_accessor(),
|
2781
|
-
end: prev(),
|
2782
|
-
});
|
2783
|
-
}
|
2784
2795
|
|
2785
|
-
if (name == "get") {
|
2786
|
-
if (!is("punc") || is("punc", "[")) {
|
2787
|
-
name = get_method_name_ast(as_property_name(), start);
|
2788
|
-
return new AST_ObjectGetter({
|
2789
|
-
start : start,
|
2790
|
-
static: is_static,
|
2791
|
-
key : name,
|
2792
|
-
quote : name instanceof AST_SymbolMethod ?
|
2793
|
-
setter_token.quote : undefined,
|
2794
|
-
value : create_accessor(),
|
2795
|
-
end : prev()
|
2796
|
-
});
|
2797
|
-
}
|
2798
|
-
} else if (name == "set") {
|
2799
|
-
if (!is("punc") || is("punc", "[")) {
|
2800
|
-
name = get_method_name_ast(as_property_name(), start);
|
2801
|
-
return new AST_ObjectSetter({
|
2802
|
-
start : start,
|
2803
|
-
static: is_static,
|
2804
|
-
key : name,
|
2805
|
-
quote : name instanceof AST_SymbolMethod ?
|
2806
|
-
setter_token.quote : undefined,
|
2807
|
-
value : create_accessor(),
|
2808
|
-
end : prev()
|
2809
|
-
});
|
2810
|
-
}
|
2811
|
-
}
|
2812
2796
|
if (is_class) {
|
2813
|
-
const key =
|
2797
|
+
const key = get_symbol_ast(name, AST_SymbolClassProperty);
|
2814
2798
|
const quote = key instanceof AST_SymbolClassProperty
|
2815
2799
|
? property_token.quote
|
2816
2800
|
: undefined;
|
2817
|
-
const AST_ClassPropertyVariant =
|
2801
|
+
const AST_ClassPropertyVariant = is_private
|
2818
2802
|
? AST_ClassPrivateProperty
|
2819
2803
|
: AST_ClassProperty;
|
2820
2804
|
if (is("operator", "=")) {
|
@@ -3036,8 +3020,17 @@ function parse($TEXT, options) {
|
|
3036
3020
|
semicolon();
|
3037
3021
|
} else if ((node = statement(is_default)) instanceof AST_Definitions && is_default) {
|
3038
3022
|
unexpected(node.start);
|
3039
|
-
} else if (
|
3023
|
+
} else if (
|
3024
|
+
node instanceof AST_Definitions
|
3025
|
+
|| node instanceof AST_Defun
|
3026
|
+
|| node instanceof AST_DefClass
|
3027
|
+
) {
|
3040
3028
|
exported_definition = node;
|
3029
|
+
} else if (
|
3030
|
+
node instanceof AST_ClassExpression
|
3031
|
+
|| node instanceof AST_Function
|
3032
|
+
) {
|
3033
|
+
exported_value = node;
|
3041
3034
|
} else if (node instanceof AST_SimpleStatement) {
|
3042
3035
|
exported_value = node.body;
|
3043
3036
|
} else {
|
@@ -3706,8 +3699,6 @@ function walk_body(node, visitor) {
|
|
3706
3699
|
function clone_block_scope(deep) {
|
3707
3700
|
var clone = this._clone(deep);
|
3708
3701
|
if (this.block_scope) {
|
3709
|
-
// TODO this is sometimes undefined during compression.
|
3710
|
-
// But it should always have a value!
|
3711
3702
|
clone.block_scope = this.block_scope.clone();
|
3712
3703
|
}
|
3713
3704
|
return clone;
|
@@ -3891,7 +3882,6 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
|
3891
3882
|
$documentation: "Base class for all statements introducing a lexical scope",
|
3892
3883
|
$propdoc: {
|
3893
3884
|
variables: "[Map/S] a map of name -> SymbolDef for all variables/functions defined in this scope",
|
3894
|
-
functions: "[Map/S] like `variables`, but only lists function declarations",
|
3895
3885
|
uses_with: "[boolean/S] tells whether this scope uses the `with` statement",
|
3896
3886
|
uses_eval: "[boolean/S] tells whether this scope contains a direct call to the global `eval`",
|
3897
3887
|
parent_scope: "[AST_Scope?/S] link to the parent scope",
|
@@ -3914,7 +3904,6 @@ var AST_Scope = DEFNODE("Scope", "variables functions uses_with uses_eval parent
|
|
3914
3904
|
});
|
3915
3905
|
} else {
|
3916
3906
|
if (this.variables) node.variables = new Map(this.variables);
|
3917
|
-
if (this.functions) node.functions = new Map(this.functions);
|
3918
3907
|
if (this.enclosed) node.enclosed = this.enclosed.slice();
|
3919
3908
|
if (this._block_scope) node._block_scope = this._block_scope;
|
3920
3909
|
}
|
@@ -4014,6 +4003,21 @@ var AST_Lambda = DEFNODE("Lambda", "name argnames uses_arguments is_generator as
|
|
4014
4003
|
|
4015
4004
|
if (this.name) push(this.name);
|
4016
4005
|
},
|
4006
|
+
is_braceless() {
|
4007
|
+
return this.body[0] instanceof AST_Return && this.body[0].value;
|
4008
|
+
},
|
4009
|
+
// Default args and expansion don't count, so .argnames.length doesn't cut it
|
4010
|
+
length_property() {
|
4011
|
+
let length = 0;
|
4012
|
+
|
4013
|
+
for (const arg of this.argnames) {
|
4014
|
+
if (arg instanceof AST_SymbolFunarg || arg instanceof AST_Destructuring) {
|
4015
|
+
length++;
|
4016
|
+
}
|
4017
|
+
}
|
4018
|
+
|
4019
|
+
return length;
|
4020
|
+
}
|
4017
4021
|
}, AST_Scope);
|
4018
4022
|
|
4019
4023
|
var AST_Accessor = DEFNODE("Accessor", null, {
|
@@ -7087,11 +7091,15 @@ function OutputStream(options) {
|
|
7087
7091
|
var do_add_mapping = mappings ? function() {
|
7088
7092
|
mappings.forEach(function(mapping) {
|
7089
7093
|
try {
|
7094
|
+
let name = !mapping.name && mapping.token.type == "name" ? mapping.token.value : mapping.name;
|
7095
|
+
if (name instanceof AST_Symbol) {
|
7096
|
+
name = name.name;
|
7097
|
+
}
|
7090
7098
|
options.source_map.add(
|
7091
7099
|
mapping.token.file,
|
7092
7100
|
mapping.line, mapping.col,
|
7093
7101
|
mapping.token.line, mapping.token.col,
|
7094
|
-
|
7102
|
+
is_basic_identifier_string(name) ? name : undefined
|
7095
7103
|
);
|
7096
7104
|
} catch(ex) {
|
7097
7105
|
// Ignore bad mapping
|
@@ -7671,6 +7679,7 @@ function OutputStream(options) {
|
|
7671
7679
|
var p = output.parent();
|
7672
7680
|
return p instanceof AST_PropAccess && p.expression === this
|
7673
7681
|
|| p instanceof AST_Call && p.expression === this
|
7682
|
+
|| p instanceof AST_Binary && p.operator === "**" && p.left === this
|
7674
7683
|
|| output.option("safari10") && p instanceof AST_UnaryPrefix;
|
7675
7684
|
});
|
7676
7685
|
|
@@ -8888,7 +8897,9 @@ function OutputStream(options) {
|
|
8888
8897
|
source = regexp_source_fix(source);
|
8889
8898
|
flags = flags ? sort_regexp_flags(flags) : "";
|
8890
8899
|
source = source.replace(r_slash_script, slash_script_replace);
|
8900
|
+
|
8891
8901
|
output.print(output.to_utf8(`/${source}/${flags}`));
|
8902
|
+
|
8892
8903
|
const parent = output.parent();
|
8893
8904
|
if (
|
8894
8905
|
parent instanceof AST_Binary
|
@@ -9183,6 +9194,10 @@ AST_Dot.prototype.shallow_cmp = mkshallow({
|
|
9183
9194
|
property: "eq"
|
9184
9195
|
});
|
9185
9196
|
|
9197
|
+
AST_DotHash.prototype.shallow_cmp = mkshallow({
|
9198
|
+
property: "eq"
|
9199
|
+
});
|
9200
|
+
|
9186
9201
|
AST_Unary.prototype.shallow_cmp = mkshallow({
|
9187
9202
|
operator: "eq"
|
9188
9203
|
});
|
@@ -9488,7 +9503,14 @@ AST_Scope.DEFMETHOD("figure_out_scope", function(options, { parent_scope = null,
|
|
9488
9503
|
// scope when we encounter the AST_Defun node (which is
|
9489
9504
|
// instanceof AST_Scope) but we get to the symbol a bit
|
9490
9505
|
// later.
|
9491
|
-
|
9506
|
+
const closest_scope = defun.parent_scope;
|
9507
|
+
|
9508
|
+
// In strict mode, function definitions are block-scoped
|
9509
|
+
node.scope = tw.directives["use strict"]
|
9510
|
+
? closest_scope
|
9511
|
+
: closest_scope.get_defun_scope();
|
9512
|
+
|
9513
|
+
mark_export(node.scope.def_function(node, defun), 1);
|
9492
9514
|
} else if (node instanceof AST_SymbolClass) {
|
9493
9515
|
mark_export(defun.def_variable(node, defun), 1);
|
9494
9516
|
} else if (node instanceof AST_SymbolImport) {
|
@@ -9667,7 +9689,6 @@ AST_Toplevel.DEFMETHOD("def_global", function(node) {
|
|
9667
9689
|
|
9668
9690
|
AST_Scope.DEFMETHOD("init_scope_vars", function(parent_scope) {
|
9669
9691
|
this.variables = new Map(); // map name to AST_SymbolVar (variables defined in this scope; includes functions)
|
9670
|
-
this.functions = new Map(); // map name to AST_SymbolDefun (functions defined in this scope)
|
9671
9692
|
this.uses_with = false; // will be set to true if this or some nested scope uses the `with` statement
|
9672
9693
|
this.uses_eval = false; // will be set to true if this or nested scope uses the global `eval`
|
9673
9694
|
this.parent_scope = parent_scope; // the parent scope
|
@@ -9830,7 +9851,6 @@ AST_Scope.DEFMETHOD("find_variable", function(name) {
|
|
9830
9851
|
AST_Scope.DEFMETHOD("def_function", function(symbol, init) {
|
9831
9852
|
var def = this.def_variable(symbol, init);
|
9832
9853
|
if (!def.init || def.init instanceof AST_Defun) def.init = init;
|
9833
|
-
this.functions.set(symbol.name, def);
|
9834
9854
|
return def;
|
9835
9855
|
});
|
9836
9856
|
|
@@ -10184,6 +10204,12 @@ AST_Node.prototype.size = function (compressor, stack) {
|
|
10184
10204
|
let size = 0;
|
10185
10205
|
walk_parent(this, (node, info) => {
|
10186
10206
|
size += node._size(info);
|
10207
|
+
|
10208
|
+
// Braceless arrow functions have fake "return" statements
|
10209
|
+
if (node instanceof AST_Arrow && node.is_braceless()) {
|
10210
|
+
size += node.body[0].value._size(info);
|
10211
|
+
return true;
|
10212
|
+
}
|
10187
10213
|
}, stack || (compressor && compressor.stack));
|
10188
10214
|
|
10189
10215
|
// just to save a bit of memory
|
@@ -10228,7 +10254,6 @@ AST_With.prototype._size = () => 6;
|
|
10228
10254
|
|
10229
10255
|
AST_Expansion.prototype._size = () => 3;
|
10230
10256
|
|
10231
|
-
/*#__INLINE__*/
|
10232
10257
|
const lambda_modifiers = func =>
|
10233
10258
|
(func.is_generator ? 1 : 0) + (func.async ? 6 : 0);
|
10234
10259
|
|
@@ -10257,7 +10282,9 @@ AST_Arrow.prototype._size = function () {
|
|
10257
10282
|
args_and_arrow += 2;
|
10258
10283
|
}
|
10259
10284
|
|
10260
|
-
|
10285
|
+
const body_overhead = this.is_braceless() ? 0 : list_overhead(this.body) + 2;
|
10286
|
+
|
10287
|
+
return lambda_modifiers(this) + args_and_arrow + body_overhead;
|
10261
10288
|
};
|
10262
10289
|
|
10263
10290
|
AST_Destructuring.prototype._size = () => 2;
|
@@ -10632,11 +10659,8 @@ const TOP = 0b0000010000000000;
|
|
10632
10659
|
|
10633
10660
|
const CLEAR_BETWEEN_PASSES = SQUEEZED | OPTIMIZED | TOP;
|
10634
10661
|
|
10635
|
-
/*@__INLINE__*/
|
10636
10662
|
const has_flag = (node, flag) => node.flags & flag;
|
10637
|
-
/*@__INLINE__*/
|
10638
10663
|
const set_flag = (node, flag) => { node.flags |= flag; };
|
10639
|
-
/*@__INLINE__*/
|
10640
10664
|
const clear_flag = (node, flag) => { node.flags &= ~flag; };
|
10641
10665
|
|
10642
10666
|
class Compressor extends TreeWalker {
|
@@ -10679,7 +10703,7 @@ class Compressor extends TreeWalker {
|
|
10679
10703
|
properties : !false_by_default,
|
10680
10704
|
pure_getters : !false_by_default && "strict",
|
10681
10705
|
pure_funcs : null,
|
10682
|
-
reduce_funcs :
|
10706
|
+
reduce_funcs : !false_by_default,
|
10683
10707
|
reduce_vars : !false_by_default,
|
10684
10708
|
sequences : !false_by_default,
|
10685
10709
|
side_effects : !false_by_default,
|
@@ -10979,7 +11003,7 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
10979
11003
|
&& parent.expression === node
|
10980
11004
|
&& !(value instanceof AST_Arrow)
|
10981
11005
|
&& !(value instanceof AST_Class)
|
10982
|
-
&& !parent.
|
11006
|
+
&& !parent.is_callee_pure(compressor)
|
10983
11007
|
&& (!(value instanceof AST_Function)
|
10984
11008
|
|| !(parent instanceof AST_New) && value.contains_this())) {
|
10985
11009
|
return true;
|
@@ -11284,9 +11308,6 @@ function is_modified(compressor, tw, node, value, level, immutable) {
|
|
11284
11308
|
return true;
|
11285
11309
|
});
|
11286
11310
|
def_reduce_vars(AST_Call, function (tw) {
|
11287
|
-
// TODO this block should just be { return } but
|
11288
|
-
// for some reason the _walk function of AST_Call walks the callee last
|
11289
|
-
|
11290
11311
|
this.expression.walk(tw);
|
11291
11312
|
|
11292
11313
|
if (this.optional) {
|
@@ -11839,8 +11860,11 @@ function tighten_body(statements, compressor) {
|
|
11839
11860
|
|| node instanceof AST_Debugger
|
11840
11861
|
|| node instanceof AST_Destructuring
|
11841
11862
|
|| node instanceof AST_Expansion
|
11842
|
-
|
11843
|
-
|
11863
|
+
&& node.expression instanceof AST_Symbol
|
11864
|
+
&& (
|
11865
|
+
node.expression instanceof AST_This
|
11866
|
+
|| node.expression.definition().references.length > 1
|
11867
|
+
)
|
11844
11868
|
|| node instanceof AST_IterationStatement && !(node instanceof AST_For)
|
11845
11869
|
|| node instanceof AST_LoopControl
|
11846
11870
|
|| node instanceof AST_Try
|
@@ -11934,6 +11958,7 @@ function tighten_body(statements, compressor) {
|
|
11934
11958
|
if (stop_after === node) abort = true;
|
11935
11959
|
if (stop_if_hit === node) stop_if_hit = null;
|
11936
11960
|
});
|
11961
|
+
|
11937
11962
|
var multi_replacer = new TreeTransformer(function(node) {
|
11938
11963
|
if (abort) return node;
|
11939
11964
|
// Skip nodes before `candidate` as quickly as possible
|
@@ -11956,6 +11981,7 @@ function tighten_body(statements, compressor) {
|
|
11956
11981
|
// Skip (non-executed) functions and (leading) default case in switch statements
|
11957
11982
|
if (node instanceof AST_Default || node instanceof AST_Scope) return node;
|
11958
11983
|
});
|
11984
|
+
|
11959
11985
|
while (--stat_index >= 0) {
|
11960
11986
|
// Treat parameters as collapsible in IIFE, i.e.
|
11961
11987
|
// function(a, b){ ... }(x());
|
@@ -12131,7 +12157,10 @@ function tighten_body(statements, compressor) {
|
|
12131
12157
|
function extract_candidates(expr) {
|
12132
12158
|
hit_stack.push(expr);
|
12133
12159
|
if (expr instanceof AST_Assign) {
|
12134
|
-
if (
|
12160
|
+
if (
|
12161
|
+
!expr.left.has_side_effects(compressor)
|
12162
|
+
&& !(expr.right instanceof AST_Chain)
|
12163
|
+
) {
|
12135
12164
|
candidates.push(hit_stack.slice());
|
12136
12165
|
}
|
12137
12166
|
extract_candidates(expr.right);
|
@@ -12194,7 +12223,7 @@ function tighten_body(statements, compressor) {
|
|
12194
12223
|
candidates.push(hit_stack.slice());
|
12195
12224
|
}
|
12196
12225
|
} else if (expr instanceof AST_VarDef) {
|
12197
|
-
if (expr.value) {
|
12226
|
+
if (expr.value && !(expr.value instanceof AST_Chain)) {
|
12198
12227
|
candidates.push(hit_stack.slice());
|
12199
12228
|
extract_candidates(expr.value);
|
12200
12229
|
}
|
@@ -13009,7 +13038,13 @@ function is_undefined(node, compressor) {
|
|
13009
13038
|
});
|
13010
13039
|
def_may_throw_on_access(AST_Dot, function(compressor) {
|
13011
13040
|
if (!is_strict(compressor)) return false;
|
13012
|
-
|
13041
|
+
|
13042
|
+
if (this.property == "prototype") {
|
13043
|
+
return !(
|
13044
|
+
this.expression instanceof AST_Function
|
13045
|
+
|| this.expression instanceof AST_Class
|
13046
|
+
);
|
13047
|
+
}
|
13013
13048
|
return true;
|
13014
13049
|
});
|
13015
13050
|
def_may_throw_on_access(AST_Chain, function(compressor) {
|
@@ -13351,9 +13386,7 @@ var static_fns = convert_to_predicate({
|
|
13351
13386
|
if (compressor.option("unsafe")) {
|
13352
13387
|
var fn = function() {};
|
13353
13388
|
fn.node = this;
|
13354
|
-
fn.toString =
|
13355
|
-
return this.node.print_to_string();
|
13356
|
-
};
|
13389
|
+
fn.toString = () => this.print_to_string();
|
13357
13390
|
return fn;
|
13358
13391
|
}
|
13359
13392
|
return this;
|
@@ -13534,6 +13567,14 @@ var static_fns = convert_to_predicate({
|
|
13534
13567
|
"POSITIVE_INFINITY",
|
13535
13568
|
],
|
13536
13569
|
});
|
13570
|
+
const regexp_flags = new Set([
|
13571
|
+
"dotAll",
|
13572
|
+
"global",
|
13573
|
+
"ignoreCase",
|
13574
|
+
"multiline",
|
13575
|
+
"sticky",
|
13576
|
+
"unicode",
|
13577
|
+
]);
|
13537
13578
|
def_eval(AST_PropAccess, function(compressor, depth) {
|
13538
13579
|
if (this.optional) {
|
13539
13580
|
const obj = this.expression._eval(compressor, depth);
|
@@ -13566,12 +13607,19 @@ var static_fns = convert_to_predicate({
|
|
13566
13607
|
val = global_objs[exp.name];
|
13567
13608
|
} else {
|
13568
13609
|
val = exp._eval(compressor, depth + 1);
|
13610
|
+
if (val instanceof RegExp) {
|
13611
|
+
if (key == "source") {
|
13612
|
+
return regexp_source_fix(val.source);
|
13613
|
+
} else if (key == "flags" || regexp_flags.has(key)) {
|
13614
|
+
return val[key];
|
13615
|
+
}
|
13616
|
+
}
|
13569
13617
|
if (!val || val === exp || !HOP(val, key)) return this;
|
13570
13618
|
if (typeof val == "function") switch (key) {
|
13571
13619
|
case "name":
|
13572
13620
|
return val.node.name ? val.node.name.name : "";
|
13573
13621
|
case "length":
|
13574
|
-
return val.node.
|
13622
|
+
return val.node.length_property();
|
13575
13623
|
default:
|
13576
13624
|
return this;
|
13577
13625
|
}
|
@@ -13623,6 +13671,7 @@ var static_fns = convert_to_predicate({
|
|
13623
13671
|
var arg = this.args[i];
|
13624
13672
|
var value = arg._eval(compressor, depth);
|
13625
13673
|
if (arg === value) return this;
|
13674
|
+
if (arg instanceof AST_Lambda) return this;
|
13626
13675
|
args.push(value);
|
13627
13676
|
}
|
13628
13677
|
try {
|
@@ -13722,7 +13771,7 @@ var static_fns = convert_to_predicate({
|
|
13722
13771
|
});
|
13723
13772
|
|
13724
13773
|
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");
|
13725
|
-
AST_Call.DEFMETHOD("
|
13774
|
+
AST_Call.DEFMETHOD("is_callee_pure", function(compressor) {
|
13726
13775
|
if (compressor.option("unsafe")) {
|
13727
13776
|
var expr = this.expression;
|
13728
13777
|
var first_arg = (this.args && this.args[0] && this.args[0].evaluate(compressor));
|
@@ -13792,7 +13841,7 @@ const pure_prop_access_globals = new Set([
|
|
13792
13841
|
});
|
13793
13842
|
def_has_side_effects(AST_Call, function(compressor) {
|
13794
13843
|
if (
|
13795
|
-
!this.
|
13844
|
+
!this.is_callee_pure(compressor)
|
13796
13845
|
&& (!this.expression.is_call_pure(compressor)
|
13797
13846
|
|| this.expression.has_side_effects(compressor))
|
13798
13847
|
) {
|
@@ -13882,7 +13931,7 @@ const pure_prop_access_globals = new Set([
|
|
13882
13931
|
|| this.expression.has_side_effects(compressor);
|
13883
13932
|
});
|
13884
13933
|
def_has_side_effects(AST_Sub, function(compressor) {
|
13885
|
-
if (this.optional && is_nullish(this.expression)) {
|
13934
|
+
if (this.optional && is_nullish(this.expression, compressor)) {
|
13886
13935
|
return false;
|
13887
13936
|
}
|
13888
13937
|
|
@@ -13952,9 +14001,9 @@ const pure_prop_access_globals = new Set([
|
|
13952
14001
|
return any(this.body, compressor);
|
13953
14002
|
});
|
13954
14003
|
def_may_throw(AST_Call, function(compressor) {
|
13955
|
-
if (this.optional && is_nullish(this.expression)) return false;
|
14004
|
+
if (this.optional && is_nullish(this.expression, compressor)) return false;
|
13956
14005
|
if (any(this.args, compressor)) return true;
|
13957
|
-
if (this.
|
14006
|
+
if (this.is_callee_pure(compressor)) return false;
|
13958
14007
|
if (this.expression.may_throw(compressor)) return true;
|
13959
14008
|
return !(this.expression instanceof AST_Lambda)
|
13960
14009
|
|| any(this.expression.body, compressor);
|
@@ -14015,7 +14064,7 @@ const pure_prop_access_globals = new Set([
|
|
14015
14064
|
|| this.expression.may_throw(compressor);
|
14016
14065
|
});
|
14017
14066
|
def_may_throw(AST_Sub, function(compressor) {
|
14018
|
-
if (this.optional && is_nullish(this.expression)) return false;
|
14067
|
+
if (this.optional && is_nullish(this.expression, compressor)) return false;
|
14019
14068
|
|
14020
14069
|
return !this.optional && this.expression.may_throw_on_access(compressor)
|
14021
14070
|
|| this.expression.may_throw(compressor)
|
@@ -14828,11 +14877,11 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
14828
14877
|
def_drop_side_effect_free(AST_Constant, return_null);
|
14829
14878
|
def_drop_side_effect_free(AST_This, return_null);
|
14830
14879
|
def_drop_side_effect_free(AST_Call, function(compressor, first_in_statement) {
|
14831
|
-
if (this.optional && is_nullish(this.expression)) {
|
14880
|
+
if (this.optional && is_nullish(this.expression, compressor)) {
|
14832
14881
|
return make_node(AST_Undefined, this);
|
14833
14882
|
}
|
14834
14883
|
|
14835
|
-
if (!this.
|
14884
|
+
if (!this.is_callee_pure(compressor)) {
|
14836
14885
|
if (this.expression.is_call_pure(compressor)) {
|
14837
14886
|
var exprs = this.args.slice();
|
14838
14887
|
exprs.unshift(this.expression.expression);
|
@@ -14975,7 +15024,7 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
14975
15024
|
});
|
14976
15025
|
def_drop_side_effect_free(AST_Dot, function(compressor, first_in_statement) {
|
14977
15026
|
if (this.optional) {
|
14978
|
-
return is_nullish(this.expression) ? make_node(AST_Undefined, this) : this;
|
15027
|
+
return is_nullish(this.expression, compressor) ? make_node(AST_Undefined, this) : this;
|
14979
15028
|
}
|
14980
15029
|
if (this.expression.may_throw_on_access(compressor)) return this;
|
14981
15030
|
|
@@ -14983,7 +15032,7 @@ AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
|
14983
15032
|
});
|
14984
15033
|
def_drop_side_effect_free(AST_Sub, function(compressor, first_in_statement) {
|
14985
15034
|
if (this.optional) {
|
14986
|
-
return is_nullish(this.expression) ? make_node(AST_Undefined, this): this;
|
15035
|
+
return is_nullish(this.expression, compressor) ? make_node(AST_Undefined, this): this;
|
14987
15036
|
}
|
14988
15037
|
if (this.expression.may_throw_on_access(compressor)) return this;
|
14989
15038
|
|
@@ -15508,11 +15557,11 @@ def_optimize(AST_Definitions, function(self) {
|
|
15508
15557
|
return self;
|
15509
15558
|
});
|
15510
15559
|
|
15511
|
-
def_optimize(AST_VarDef, function(self) {
|
15560
|
+
def_optimize(AST_VarDef, function(self, compressor) {
|
15512
15561
|
if (
|
15513
15562
|
self.name instanceof AST_SymbolLet
|
15514
15563
|
&& self.value != null
|
15515
|
-
&& is_undefined(self.value)
|
15564
|
+
&& is_undefined(self.value, compressor)
|
15516
15565
|
) {
|
15517
15566
|
self.value = null;
|
15518
15567
|
}
|
@@ -15550,7 +15599,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
15550
15599
|
}
|
15551
15600
|
}
|
15552
15601
|
|
15553
|
-
if (self.optional && is_nullish(fn)) {
|
15602
|
+
if (self.optional && is_nullish(fn, compressor)) {
|
15554
15603
|
return make_node(AST_Undefined, self);
|
15555
15604
|
}
|
15556
15605
|
|
@@ -15852,7 +15901,7 @@ def_optimize(AST_Call, function(self, compressor) {
|
|
15852
15901
|
|
15853
15902
|
var stat = is_func && fn.body[0];
|
15854
15903
|
var is_regular_func = is_func && !fn.is_generator && !fn.async;
|
15855
|
-
var can_inline = is_regular_func && compressor.option("inline") && !self.
|
15904
|
+
var can_inline = is_regular_func && compressor.option("inline") && !self.is_callee_pure(compressor);
|
15856
15905
|
if (can_inline && stat instanceof AST_Return) {
|
15857
15906
|
let returned = stat.value;
|
15858
15907
|
if (!returned || returned.is_constant_expression()) {
|
@@ -16576,7 +16625,7 @@ def_optimize(AST_Binary, function(self, compressor) {
|
|
16576
16625
|
}
|
16577
16626
|
break;
|
16578
16627
|
case "??":
|
16579
|
-
if (is_nullish(self.left)) {
|
16628
|
+
if (is_nullish(self.left, compressor)) {
|
16580
16629
|
return self.right;
|
16581
16630
|
}
|
16582
16631
|
|
@@ -16878,19 +16927,26 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
16878
16927
|
let fixed = self.fixed_value();
|
16879
16928
|
let single_use = def.single_use
|
16880
16929
|
&& !(parent instanceof AST_Call
|
16881
|
-
&& (parent.
|
16930
|
+
&& (parent.is_callee_pure(compressor))
|
16882
16931
|
|| has_annotation(parent, _NOINLINE))
|
16883
16932
|
&& !(parent instanceof AST_Export
|
16884
16933
|
&& fixed instanceof AST_Lambda
|
16885
16934
|
&& fixed.name);
|
16886
16935
|
|
16936
|
+
if (single_use && fixed instanceof AST_Node) {
|
16937
|
+
single_use =
|
16938
|
+
!fixed.has_side_effects(compressor)
|
16939
|
+
&& !fixed.may_throw(compressor);
|
16940
|
+
}
|
16941
|
+
|
16887
16942
|
if (single_use && (fixed instanceof AST_Lambda || fixed instanceof AST_Class)) {
|
16888
16943
|
if (retain_top_func(fixed, compressor)) {
|
16889
16944
|
single_use = false;
|
16890
16945
|
} else if (def.scope !== self.scope
|
16891
16946
|
&& (def.escaped == 1
|
16892
16947
|
|| has_flag(fixed, INLINED)
|
16893
|
-
|| within_array_or_object_literal(compressor)
|
16948
|
+
|| within_array_or_object_literal(compressor)
|
16949
|
+
|| !compressor.option("reduce_funcs"))) {
|
16894
16950
|
single_use = false;
|
16895
16951
|
} else if (recursive_ref(compressor, def)) {
|
16896
16952
|
single_use = false;
|
@@ -16906,6 +16962,7 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
16906
16962
|
}
|
16907
16963
|
}
|
16908
16964
|
}
|
16965
|
+
|
16909
16966
|
if (single_use && fixed instanceof AST_Lambda) {
|
16910
16967
|
single_use =
|
16911
16968
|
def.scope === self.scope
|
@@ -16915,15 +16972,6 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
16915
16972
|
&& !scope_encloses_variables_in_this_scope(nearest_scope, fixed)
|
16916
16973
|
&& !(fixed.name && fixed.name.definition().recursive_refs > 0);
|
16917
16974
|
}
|
16918
|
-
if (single_use && fixed instanceof AST_Class) {
|
16919
|
-
const extends_inert = !fixed.extends
|
16920
|
-
|| !fixed.extends.may_throw(compressor)
|
16921
|
-
&& !fixed.extends.has_side_effects(compressor);
|
16922
|
-
single_use = extends_inert
|
16923
|
-
&& !fixed.properties.some(prop =>
|
16924
|
-
prop.may_throw(compressor) || prop.has_side_effects(compressor)
|
16925
|
-
);
|
16926
|
-
}
|
16927
16975
|
|
16928
16976
|
if (single_use && fixed) {
|
16929
16977
|
if (fixed instanceof AST_DefClass) {
|
@@ -17000,6 +17048,7 @@ def_optimize(AST_SymbolRef, function(self, compressor) {
|
|
17000
17048
|
}
|
17001
17049
|
}
|
17002
17050
|
}
|
17051
|
+
|
17003
17052
|
return self;
|
17004
17053
|
});
|
17005
17054
|
|
@@ -17184,20 +17233,20 @@ def_optimize(AST_DefaultAssign, function(self, compressor) {
|
|
17184
17233
|
return self;
|
17185
17234
|
});
|
17186
17235
|
|
17187
|
-
function is_nullish(node) {
|
17236
|
+
function is_nullish(node, compressor) {
|
17188
17237
|
let fixed;
|
17189
17238
|
return (
|
17190
17239
|
node instanceof AST_Null
|
17191
|
-
|| is_undefined(node)
|
17240
|
+
|| is_undefined(node, compressor)
|
17192
17241
|
|| (
|
17193
17242
|
node instanceof AST_SymbolRef
|
17194
17243
|
&& (fixed = node.definition().fixed) instanceof AST_Node
|
17195
|
-
&& is_nullish(fixed)
|
17244
|
+
&& is_nullish(fixed, compressor)
|
17196
17245
|
)
|
17197
17246
|
// Recurse into those optional chains!
|
17198
|
-
|| node instanceof AST_PropAccess && node.optional && is_nullish(node.expression)
|
17199
|
-
|| node instanceof AST_Call && node.optional && is_nullish(node.expression)
|
17200
|
-
|| node instanceof AST_Chain && is_nullish(node.expression)
|
17247
|
+
|| node instanceof AST_PropAccess && node.optional && is_nullish(node.expression, compressor)
|
17248
|
+
|| node instanceof AST_Call && node.optional && is_nullish(node.expression, compressor)
|
17249
|
+
|| node instanceof AST_Chain && is_nullish(node.expression, compressor)
|
17201
17250
|
);
|
17202
17251
|
}
|
17203
17252
|
|
@@ -17212,8 +17261,8 @@ function is_nullish_check(check, check_subject, compressor) {
|
|
17212
17261
|
&& check.operator === "=="
|
17213
17262
|
// which side is nullish?
|
17214
17263
|
&& (
|
17215
|
-
(nullish_side = is_nullish(check.left) && check.left)
|
17216
|
-
|| (nullish_side = is_nullish(check.right) && check.right)
|
17264
|
+
(nullish_side = is_nullish(check.left, compressor) && check.left)
|
17265
|
+
|| (nullish_side = is_nullish(check.right, compressor) && check.right)
|
17217
17266
|
)
|
17218
17267
|
// is the other side the same as the check_subject
|
17219
17268
|
&& (
|
@@ -17251,12 +17300,12 @@ function is_nullish_check(check, check_subject, compressor) {
|
|
17251
17300
|
null_cmp = cmp;
|
17252
17301
|
defined_side = cmp.left;
|
17253
17302
|
}
|
17254
|
-
if (is_undefined(cmp.left)) {
|
17303
|
+
if (is_undefined(cmp.left, compressor)) {
|
17255
17304
|
found++;
|
17256
17305
|
undefined_cmp = cmp;
|
17257
17306
|
defined_side = cmp.right;
|
17258
17307
|
}
|
17259
|
-
if (is_undefined(cmp.right)) {
|
17308
|
+
if (is_undefined(cmp.right, compressor)) {
|
17260
17309
|
found++;
|
17261
17310
|
undefined_cmp = cmp;
|
17262
17311
|
defined_side = cmp.left;
|
@@ -17586,27 +17635,40 @@ function safe_to_flatten(value, compressor) {
|
|
17586
17635
|
|
17587
17636
|
AST_PropAccess.DEFMETHOD("flatten_object", function(key, compressor) {
|
17588
17637
|
if (!compressor.option("properties")) return;
|
17638
|
+
if (key === "__proto__") return;
|
17639
|
+
|
17589
17640
|
var arrows = compressor.option("unsafe_arrows") && compressor.option("ecma") >= 2015;
|
17590
17641
|
var expr = this.expression;
|
17591
17642
|
if (expr instanceof AST_Object) {
|
17592
17643
|
var props = expr.properties;
|
17644
|
+
|
17593
17645
|
for (var i = props.length; --i >= 0;) {
|
17594
17646
|
var prop = props[i];
|
17647
|
+
|
17595
17648
|
if ("" + (prop instanceof AST_ConciseMethod ? prop.key.name : prop.key) == key) {
|
17596
|
-
|
17597
|
-
|
17598
|
-
|| arrows &&
|
17599
|
-
|
17600
|
-
|
17649
|
+
const all_props_flattenable = props.every((p) =>
|
17650
|
+
(p instanceof AST_ObjectKeyVal
|
17651
|
+
|| arrows && p instanceof AST_ConciseMethod && !p.is_generator
|
17652
|
+
)
|
17653
|
+
&& !p.computed_key()
|
17654
|
+
);
|
17655
|
+
|
17656
|
+
if (!all_props_flattenable) return;
|
17657
|
+
if (!safe_to_flatten(prop.value, compressor)) return;
|
17658
|
+
|
17601
17659
|
return make_node(AST_Sub, this, {
|
17602
17660
|
expression: make_node(AST_Array, expr, {
|
17603
17661
|
elements: props.map(function(prop) {
|
17604
17662
|
var v = prop.value;
|
17605
|
-
if (v instanceof AST_Accessor)
|
17663
|
+
if (v instanceof AST_Accessor) {
|
17664
|
+
v = make_node(AST_Function, v, v);
|
17665
|
+
}
|
17666
|
+
|
17606
17667
|
var k = prop.key;
|
17607
17668
|
if (k instanceof AST_Node && !(k instanceof AST_SymbolMethod)) {
|
17608
17669
|
return make_sequence(prop, [ k, v ]);
|
17609
17670
|
}
|
17671
|
+
|
17610
17672
|
return v;
|
17611
17673
|
})
|
17612
17674
|
}),
|
@@ -17744,7 +17806,7 @@ def_optimize(AST_Sub, function(self, compressor) {
|
|
17744
17806
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
17745
17807
|
return best_of(compressor, ev, self);
|
17746
17808
|
}
|
17747
|
-
if (self.optional && is_nullish(self.expression)) {
|
17809
|
+
if (self.optional && is_nullish(self.expression, compressor)) {
|
17748
17810
|
return make_node(AST_Undefined, self);
|
17749
17811
|
}
|
17750
17812
|
return self;
|
@@ -17818,7 +17880,7 @@ def_optimize(AST_Dot, function(self, compressor) {
|
|
17818
17880
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
17819
17881
|
return best_of(compressor, ev, self);
|
17820
17882
|
}
|
17821
|
-
if (self.optional && is_nullish(self.expression)) {
|
17883
|
+
if (self.optional && is_nullish(self.expression, compressor)) {
|
17822
17884
|
return make_node(AST_Undefined, self);
|
17823
17885
|
}
|
17824
17886
|
return self;
|
@@ -17862,7 +17924,7 @@ def_optimize(AST_Array, function(self, compressor) {
|
|
17862
17924
|
return self;
|
17863
17925
|
});
|
17864
17926
|
|
17865
|
-
function inline_object_prop_spread(props) {
|
17927
|
+
function inline_object_prop_spread(props, compressor) {
|
17866
17928
|
for (var i = 0; i < props.length; i++) {
|
17867
17929
|
var prop = props[i];
|
17868
17930
|
if (prop instanceof AST_Expansion) {
|
@@ -17880,6 +17942,9 @@ function inline_object_prop_spread(props) {
|
|
17880
17942
|
// non-iterable value silently does nothing; it is thus safe
|
17881
17943
|
// to remove. AST_String is the only iterable AST_Constant.
|
17882
17944
|
props.splice(i, 1);
|
17945
|
+
} else if (is_nullish(expr, compressor)) {
|
17946
|
+
// Likewise, null and undefined can be silently removed.
|
17947
|
+
props.splice(i, 1);
|
17883
17948
|
}
|
17884
17949
|
}
|
17885
17950
|
}
|
@@ -17890,7 +17955,7 @@ def_optimize(AST_Object, function(self, compressor) {
|
|
17890
17955
|
if (optimized !== self) {
|
17891
17956
|
return optimized;
|
17892
17957
|
}
|
17893
|
-
inline_object_prop_spread(self.properties);
|
17958
|
+
inline_object_prop_spread(self.properties, compressor);
|
17894
17959
|
return self;
|
17895
17960
|
});
|
17896
17961
|
|
@@ -17983,7 +18048,7 @@ def_optimize(AST_TemplateString, function(self, compressor) {
|
|
17983
18048
|
&& (
|
17984
18049
|
segments[1].is_string(compressor)
|
17985
18050
|
|| segments[1].is_number(compressor)
|
17986
|
-
|| is_nullish(segments[1])
|
18051
|
+
|| is_nullish(segments[1], compressor)
|
17987
18052
|
|| compressor.option("unsafe")
|
17988
18053
|
)
|
17989
18054
|
) {
|
@@ -22374,6 +22439,7 @@ var domprops = [
|
|
22374
22439
|
"exponent",
|
22375
22440
|
"exponentialRampToValueAtTime",
|
22376
22441
|
"exportKey",
|
22442
|
+
"exports",
|
22377
22443
|
"extend",
|
22378
22444
|
"extensions",
|
22379
22445
|
"extentNode",
|
@@ -26405,6 +26471,7 @@ async function minify(files, options) {
|
|
26405
26471
|
rename: undefined,
|
26406
26472
|
safari10: false,
|
26407
26473
|
sourceMap: false,
|
26474
|
+
spidermonkey: false,
|
26408
26475
|
timings: false,
|
26409
26476
|
toplevel: false,
|
26410
26477
|
warnings: false,
|
@@ -26476,20 +26543,32 @@ async function minify(files, options) {
|
|
26476
26543
|
if (files instanceof AST_Toplevel) {
|
26477
26544
|
toplevel = files;
|
26478
26545
|
} else {
|
26479
|
-
if (typeof files == "string") {
|
26546
|
+
if (typeof files == "string" || (options.parse.spidermonkey && !Array.isArray(files))) {
|
26480
26547
|
files = [ files ];
|
26481
26548
|
}
|
26482
26549
|
options.parse = options.parse || {};
|
26483
26550
|
options.parse.toplevel = null;
|
26484
|
-
|
26485
|
-
|
26486
|
-
options.parse.toplevel =
|
26487
|
-
|
26488
|
-
|
26489
|
-
|
26490
|
-
|
26551
|
+
|
26552
|
+
if (options.parse.spidermonkey) {
|
26553
|
+
options.parse.toplevel = AST_Node.from_mozilla_ast(Object.keys(files).reduce(function(toplevel, name) {
|
26554
|
+
if (!toplevel) return files[name];
|
26555
|
+
toplevel.body = toplevel.body.concat(files[name].body);
|
26556
|
+
return toplevel;
|
26557
|
+
}, null));
|
26558
|
+
} else {
|
26559
|
+
delete options.parse.spidermonkey;
|
26560
|
+
|
26561
|
+
for (var name in files) if (HOP(files, name)) {
|
26562
|
+
options.parse.filename = name;
|
26563
|
+
options.parse.toplevel = parse(files[name], options.parse);
|
26564
|
+
if (options.sourceMap && options.sourceMap.content == "inline") {
|
26565
|
+
if (Object.keys(files).length > 1)
|
26566
|
+
throw new Error("inline source map only works with singular input");
|
26567
|
+
options.sourceMap.content = read_source_map(files[name]);
|
26568
|
+
}
|
26491
26569
|
}
|
26492
26570
|
}
|
26571
|
+
|
26493
26572
|
toplevel = options.parse.toplevel;
|
26494
26573
|
}
|
26495
26574
|
if (quoted_props && options.mangle.properties.keep_quoted !== "strict") {
|
@@ -26525,6 +26604,9 @@ async function minify(files, options) {
|
|
26525
26604
|
if (options.format.ast) {
|
26526
26605
|
result.ast = toplevel;
|
26527
26606
|
}
|
26607
|
+
if (options.format.spidermonkey) {
|
26608
|
+
result.ast = toplevel.to_mozilla_ast();
|
26609
|
+
}
|
26528
26610
|
if (!HOP(options.format, "code") || options.format.code) {
|
26529
26611
|
if (options.sourceMap) {
|
26530
26612
|
options.format.source_map = await SourceMap({
|
@@ -26542,6 +26624,7 @@ async function minify(files, options) {
|
|
26542
26624
|
}
|
26543
26625
|
delete options.format.ast;
|
26544
26626
|
delete options.format.code;
|
26627
|
+
delete options.format.spidermonkey;
|
26545
26628
|
var stream = OutputStream(options.format);
|
26546
26629
|
toplevel.print(stream);
|
26547
26630
|
result.code = stream.get();
|
@@ -26834,7 +26917,6 @@ async function run_cli({ program, packageJson, fs, path }) {
|
|
26834
26917
|
case "enclosed":
|
26835
26918
|
return value.length ? value.map(symdef) : undefined;
|
26836
26919
|
case "variables":
|
26837
|
-
case "functions":
|
26838
26920
|
case "globals":
|
26839
26921
|
return value.size ? collect_from_map(value, symdef) : undefined;
|
26840
26922
|
}
|
@@ -26847,7 +26929,6 @@ async function run_cli({ program, packageJson, fs, path }) {
|
|
26847
26929
|
};
|
26848
26930
|
if (value.block_scope) {
|
26849
26931
|
result.variables = value.block_scope.variables;
|
26850
|
-
result.functions = value.block_scope.functions;
|
26851
26932
|
result.enclosed = value.block_scope.enclosed;
|
26852
26933
|
}
|
26853
26934
|
value.CTOR.PROPS.forEach(function(prop) {
|