terser 3.7.6 → 3.8.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.
Potentially problematic release.
This version of terser might be problematic. Click here for more details.
- package/README.md +55 -15
- package/bin/uglifyjs +19 -7
- package/dist/.gitkeep +0 -0
- package/dist/browser.bundle.js +11960 -0
- package/dist/browser.bundle.js.map +1 -0
- package/lib/ast.js +46 -47
- package/lib/compress.js +309 -254
- package/lib/minify.js +1 -1
- package/lib/mozilla-ast.js +31 -31
- package/lib/output.js +217 -213
- package/lib/parse.js +128 -108
- package/lib/propmangle.js +4 -4
- package/lib/scope.js +19 -19
- package/lib/sourcemap.js +3 -3
- package/lib/transform.js +37 -37
- package/lib/utils.js +29 -29
- package/package.json +35 -6
- package/tools/colorless-console.js +3 -2
- package/tools/exports.js +3 -3
package/lib/compress.js
CHANGED
@@ -49,7 +49,7 @@ function Compressor(options, false_by_default) {
|
|
49
49
|
TreeTransformer.call(this, this.before, this.after);
|
50
50
|
if (options.defaults !== undefined && !options.defaults) false_by_default = true;
|
51
51
|
this.options = defaults(options, {
|
52
|
-
arguments :
|
52
|
+
arguments : false,
|
53
53
|
arrows : !false_by_default,
|
54
54
|
booleans : !false_by_default,
|
55
55
|
collapse_vars : !false_by_default,
|
@@ -58,6 +58,7 @@ function Compressor(options, false_by_default) {
|
|
58
58
|
conditionals : !false_by_default,
|
59
59
|
dead_code : !false_by_default,
|
60
60
|
defaults : true,
|
61
|
+
directives : !false_by_default,
|
61
62
|
drop_console : false,
|
62
63
|
drop_debugger : !false_by_default,
|
63
64
|
ecma : 5,
|
@@ -149,11 +150,11 @@ function Compressor(options, false_by_default) {
|
|
149
150
|
var sequences = this.options["sequences"];
|
150
151
|
this.sequences_limit = sequences == 1 ? 800 : sequences | 0;
|
151
152
|
this.warnings_produced = {};
|
152
|
-
}
|
153
|
+
}
|
153
154
|
|
154
155
|
Compressor.prototype = new TreeTransformer;
|
155
156
|
merge(Compressor.prototype, {
|
156
|
-
option: function(key) { return this.options[key] },
|
157
|
+
option: function(key) { return this.options[key]; },
|
157
158
|
exposed: function(def) {
|
158
159
|
if (def.export) return true;
|
159
160
|
if (def.global) for (var i = 0, len = def.orig.length; i < len; i++)
|
@@ -264,10 +265,10 @@ merge(Compressor.prototype, {
|
|
264
265
|
}
|
265
266
|
});
|
266
267
|
|
267
|
-
(function(){
|
268
|
+
(function() {
|
268
269
|
|
269
270
|
function OPT(node, optimizer) {
|
270
|
-
node.DEFMETHOD("optimize", function(compressor){
|
271
|
+
node.DEFMETHOD("optimize", function(compressor) {
|
271
272
|
var self = this;
|
272
273
|
if (self._optimized) return self;
|
273
274
|
if (compressor.has_directive("use asm")) return self;
|
@@ -275,13 +276,13 @@ merge(Compressor.prototype, {
|
|
275
276
|
opt._optimized = true;
|
276
277
|
return opt;
|
277
278
|
});
|
278
|
-
}
|
279
|
+
}
|
279
280
|
|
280
|
-
OPT(AST_Node, function(self, compressor){
|
281
|
+
OPT(AST_Node, function(self, compressor) {
|
281
282
|
return self;
|
282
283
|
});
|
283
284
|
|
284
|
-
AST_Node.DEFMETHOD("equivalent_to", function(node){
|
285
|
+
AST_Node.DEFMETHOD("equivalent_to", function(node) {
|
285
286
|
return this.TYPE == node.TYPE && this.print_to_string() == node.print_to_string();
|
286
287
|
});
|
287
288
|
|
@@ -377,7 +378,7 @@ merge(Compressor.prototype, {
|
|
377
378
|
}
|
378
379
|
}
|
379
380
|
|
380
|
-
(function(def){
|
381
|
+
(function(def) {
|
381
382
|
def(AST_Node, noop);
|
382
383
|
|
383
384
|
function reset_def(compressor, def) {
|
@@ -430,6 +431,7 @@ merge(Compressor.prototype, {
|
|
430
431
|
}
|
431
432
|
|
432
433
|
function safe_to_read(tw, def) {
|
434
|
+
if (def.single_use == "m") return false;
|
433
435
|
if (tw.safe_ids[def.id]) {
|
434
436
|
if (def.fixed == null) {
|
435
437
|
var orig = def.orig[0];
|
@@ -532,14 +534,15 @@ merge(Compressor.prototype, {
|
|
532
534
|
var sym = node.left;
|
533
535
|
if (!(sym instanceof AST_SymbolRef)) return;
|
534
536
|
var d = sym.definition();
|
537
|
+
var safe = safe_to_assign(tw, d, sym.scope, node.right);
|
538
|
+
d.assignments++;
|
539
|
+
if (!safe) return;
|
535
540
|
var fixed = d.fixed;
|
536
541
|
if (!fixed && node.operator != "=") return;
|
537
|
-
if (!safe_to_assign(tw, d, sym.scope, node.right)) return;
|
538
542
|
var eq = node.operator == "=";
|
539
543
|
var value = eq ? node.right : node;
|
540
544
|
if (is_modified(compressor, tw, node, value, 0)) return;
|
541
545
|
d.references.push(sym);
|
542
|
-
d.assignments++;
|
543
546
|
if (!eq) d.chained = true;
|
544
547
|
d.fixed = eq ? function() {
|
545
548
|
return node.right;
|
@@ -582,7 +585,7 @@ merge(Compressor.prototype, {
|
|
582
585
|
descend();
|
583
586
|
pop(tw);
|
584
587
|
return true;
|
585
|
-
})
|
588
|
+
});
|
586
589
|
def(AST_Conditional, function(tw) {
|
587
590
|
this.condition.walk(tw);
|
588
591
|
push(tw);
|
@@ -674,7 +677,7 @@ merge(Compressor.prototype, {
|
|
674
677
|
node.argnames.forEach(function(arg, i) {
|
675
678
|
if (!arg.definition) return;
|
676
679
|
var d = arg.definition();
|
677
|
-
if (!node.uses_arguments
|
680
|
+
if (d.fixed === undefined && (!node.uses_arguments || tw.has_directive("use strict"))) {
|
678
681
|
d.fixed = function() {
|
679
682
|
return iife.args[i] || make_node(AST_Undefined, iife);
|
680
683
|
};
|
@@ -721,7 +724,7 @@ merge(Compressor.prototype, {
|
|
721
724
|
tw.loop_ids[d.id] = tw.in_loop;
|
722
725
|
}
|
723
726
|
var value;
|
724
|
-
if (d.fixed === undefined || !safe_to_read(tw, d)
|
727
|
+
if (d.fixed === undefined || !safe_to_read(tw, d)) {
|
725
728
|
d.fixed = false;
|
726
729
|
} else if (d.fixed) {
|
727
730
|
value = this.fixed_value();
|
@@ -766,13 +769,15 @@ merge(Compressor.prototype, {
|
|
766
769
|
def(AST_Unary, function(tw, descend) {
|
767
770
|
var node = this;
|
768
771
|
if (node.operator != "++" && node.operator != "--") return;
|
769
|
-
|
770
|
-
|
772
|
+
var exp = node.expression;
|
773
|
+
if (!(exp instanceof AST_SymbolRef)) return;
|
774
|
+
var d = exp.definition();
|
775
|
+
var safe = safe_to_assign(tw, d, true);
|
776
|
+
d.assignments++;
|
777
|
+
if (!safe) return;
|
771
778
|
var fixed = d.fixed;
|
772
779
|
if (!fixed) return;
|
773
|
-
|
774
|
-
d.references.push(node.expression);
|
775
|
-
d.assignments++;
|
780
|
+
d.references.push(exp);
|
776
781
|
d.chained = true;
|
777
782
|
d.fixed = function() {
|
778
783
|
return make_node(AST_Binary, node, {
|
@@ -821,7 +826,7 @@ merge(Compressor.prototype, {
|
|
821
826
|
tw.in_loop = saved_loop;
|
822
827
|
return true;
|
823
828
|
});
|
824
|
-
})(function(node, func){
|
829
|
+
})(function(node, func) {
|
825
830
|
node.DEFMETHOD("reduce_vars", func);
|
826
831
|
});
|
827
832
|
|
@@ -901,7 +906,7 @@ merge(Compressor.prototype, {
|
|
901
906
|
if (!props.end) props.end = orig.end;
|
902
907
|
}
|
903
908
|
return new ctor(props);
|
904
|
-
}
|
909
|
+
}
|
905
910
|
|
906
911
|
function make_sequence(orig, expressions) {
|
907
912
|
if (expressions.length == 1) return expressions[0];
|
@@ -943,7 +948,7 @@ merge(Compressor.prototype, {
|
|
943
948
|
type: typeof val
|
944
949
|
}));
|
945
950
|
}
|
946
|
-
}
|
951
|
+
}
|
947
952
|
|
948
953
|
// we shouldn't compress (1,func)(something) to
|
949
954
|
// func(something) because that changes the meaning of
|
@@ -972,14 +977,14 @@ merge(Compressor.prototype, {
|
|
972
977
|
if (thing instanceof AST_EmptyStatement) return [];
|
973
978
|
if (thing instanceof AST_Statement) return [ thing ];
|
974
979
|
throw new Error("Can't convert thing to statement array");
|
975
|
-
}
|
980
|
+
}
|
976
981
|
|
977
982
|
function is_empty(thing) {
|
978
983
|
if (thing === null) return true;
|
979
984
|
if (thing instanceof AST_EmptyStatement) return true;
|
980
985
|
if (thing instanceof AST_BlockStatement) return thing.body.length == 0;
|
981
986
|
return false;
|
982
|
-
}
|
987
|
+
}
|
983
988
|
|
984
989
|
function can_be_evicted_from_block(node) {
|
985
990
|
return !(
|
@@ -997,7 +1002,7 @@ merge(Compressor.prototype, {
|
|
997
1002
|
return x.body instanceof AST_BlockStatement ? x.body : x;
|
998
1003
|
}
|
999
1004
|
return x;
|
1000
|
-
}
|
1005
|
+
}
|
1001
1006
|
|
1002
1007
|
function is_iife_call(node) {
|
1003
1008
|
if (node.TYPE != "Call") return false;
|
@@ -1102,6 +1107,7 @@ merge(Compressor.prototype, {
|
|
1102
1107
|
|| node instanceof AST_LoopControl
|
1103
1108
|
|| node instanceof AST_Try
|
1104
1109
|
|| node instanceof AST_With
|
1110
|
+
|| node instanceof AST_Yield
|
1105
1111
|
|| parent instanceof AST_For && node !== parent.init
|
1106
1112
|
|| !replace_all
|
1107
1113
|
&& (node instanceof AST_SymbolRef && !node.is_declared(compressor))) {
|
@@ -1384,7 +1390,13 @@ merge(Compressor.prototype, {
|
|
1384
1390
|
extract_candidates(expr.alternative);
|
1385
1391
|
} else if (expr instanceof AST_Definitions
|
1386
1392
|
&& (compressor.option("unused") || !(expr instanceof AST_Const))) {
|
1387
|
-
expr.definitions.
|
1393
|
+
var len = expr.definitions.length;
|
1394
|
+
// limit number of trailing variable definitions for consideration
|
1395
|
+
var i = len - 200;
|
1396
|
+
if (i < 0) i = 0;
|
1397
|
+
for (; i < len; i++) {
|
1398
|
+
extract_candidates(expr.definitions[i]);
|
1399
|
+
}
|
1388
1400
|
} else if (expr instanceof AST_DWLoop) {
|
1389
1401
|
extract_candidates(expr.condition);
|
1390
1402
|
if (!(expr.body instanceof AST_Block)) {
|
@@ -1921,7 +1933,7 @@ merge(Compressor.prototype, {
|
|
1921
1933
|
CHANGED = true;
|
1922
1934
|
var left = prev.body;
|
1923
1935
|
return make_sequence(left, [ left, right ]).transform(compressor);
|
1924
|
-
}
|
1936
|
+
}
|
1925
1937
|
var n = 0, prev;
|
1926
1938
|
for (var i = 0; i < statements.length; i++) {
|
1927
1939
|
var stat = statements[i];
|
@@ -2112,7 +2124,7 @@ merge(Compressor.prototype, {
|
|
2112
2124
|
if (!(stat instanceof AST_Defun)) {
|
2113
2125
|
compressor.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start);
|
2114
2126
|
}
|
2115
|
-
stat.walk(new TreeWalker(function(node){
|
2127
|
+
stat.walk(new TreeWalker(function(node) {
|
2116
2128
|
if (node instanceof AST_Var) {
|
2117
2129
|
compressor.warn("Declarations in unreachable code! [{file}:{line},{col}]", node.start);
|
2118
2130
|
node.remove_initializers();
|
@@ -2134,7 +2146,7 @@ merge(Compressor.prototype, {
|
|
2134
2146
|
return true;
|
2135
2147
|
}
|
2136
2148
|
}));
|
2137
|
-
}
|
2149
|
+
}
|
2138
2150
|
|
2139
2151
|
function get_value(key) {
|
2140
2152
|
if (key instanceof AST_Constant) {
|
@@ -2193,15 +2205,15 @@ merge(Compressor.prototype, {
|
|
2193
2205
|
def(AST_Binary, function(compressor) {
|
2194
2206
|
return (this.operator == "&&" || this.operator == "||")
|
2195
2207
|
&& (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
|
2196
|
-
})
|
2208
|
+
});
|
2197
2209
|
def(AST_Assign, function(compressor) {
|
2198
2210
|
return this.operator == "="
|
2199
2211
|
&& this.right._dot_throw(compressor);
|
2200
|
-
})
|
2212
|
+
});
|
2201
2213
|
def(AST_Conditional, function(compressor) {
|
2202
2214
|
return this.consequent._dot_throw(compressor)
|
2203
2215
|
|| this.alternative._dot_throw(compressor);
|
2204
|
-
})
|
2216
|
+
});
|
2205
2217
|
def(AST_Dot, function(compressor) {
|
2206
2218
|
if (!is_strict(compressor)) return false;
|
2207
2219
|
if (this.expression instanceof AST_Function && this.property == "prototype") return false;
|
@@ -2225,86 +2237,86 @@ merge(Compressor.prototype, {
|
|
2225
2237
|
/* -----[ boolean/negation helpers ]----- */
|
2226
2238
|
|
2227
2239
|
// methods to determine whether an expression has a boolean result type
|
2228
|
-
(function(def){
|
2240
|
+
(function(def) {
|
2229
2241
|
var unary_bool = [ "!", "delete" ];
|
2230
2242
|
var binary_bool = [ "in", "instanceof", "==", "!=", "===", "!==", "<", "<=", ">=", ">" ];
|
2231
2243
|
def(AST_Node, return_false);
|
2232
|
-
def(AST_UnaryPrefix, function(){
|
2244
|
+
def(AST_UnaryPrefix, function() {
|
2233
2245
|
return member(this.operator, unary_bool);
|
2234
2246
|
});
|
2235
|
-
def(AST_Binary, function(){
|
2247
|
+
def(AST_Binary, function() {
|
2236
2248
|
return member(this.operator, binary_bool)
|
2237
2249
|
|| lazy_op(this.operator)
|
2238
2250
|
&& this.left.is_boolean()
|
2239
2251
|
&& this.right.is_boolean();
|
2240
2252
|
});
|
2241
|
-
def(AST_Conditional, function(){
|
2253
|
+
def(AST_Conditional, function() {
|
2242
2254
|
return this.consequent.is_boolean() && this.alternative.is_boolean();
|
2243
2255
|
});
|
2244
|
-
def(AST_Assign, function(){
|
2256
|
+
def(AST_Assign, function() {
|
2245
2257
|
return this.operator == "=" && this.right.is_boolean();
|
2246
2258
|
});
|
2247
|
-
def(AST_Sequence, function(){
|
2259
|
+
def(AST_Sequence, function() {
|
2248
2260
|
return this.tail_node().is_boolean();
|
2249
2261
|
});
|
2250
2262
|
def(AST_True, return_true);
|
2251
2263
|
def(AST_False, return_true);
|
2252
|
-
})(function(node, func){
|
2264
|
+
})(function(node, func) {
|
2253
2265
|
node.DEFMETHOD("is_boolean", func);
|
2254
2266
|
});
|
2255
2267
|
|
2256
2268
|
// methods to determine if an expression has a numeric result type
|
2257
|
-
(function(def){
|
2269
|
+
(function(def) {
|
2258
2270
|
def(AST_Node, return_false);
|
2259
2271
|
def(AST_Number, return_true);
|
2260
2272
|
var unary = makePredicate("+ - ~ ++ --");
|
2261
|
-
def(AST_Unary, function(){
|
2273
|
+
def(AST_Unary, function() {
|
2262
2274
|
return unary(this.operator);
|
2263
2275
|
});
|
2264
2276
|
var binary = makePredicate("- * / % & | ^ << >> >>>");
|
2265
|
-
def(AST_Binary, function(compressor){
|
2277
|
+
def(AST_Binary, function(compressor) {
|
2266
2278
|
return binary(this.operator) || this.operator == "+"
|
2267
2279
|
&& this.left.is_number(compressor)
|
2268
2280
|
&& this.right.is_number(compressor);
|
2269
2281
|
});
|
2270
|
-
def(AST_Assign, function(compressor){
|
2282
|
+
def(AST_Assign, function(compressor) {
|
2271
2283
|
return binary(this.operator.slice(0, -1))
|
2272
2284
|
|| this.operator == "=" && this.right.is_number(compressor);
|
2273
2285
|
});
|
2274
|
-
def(AST_Sequence, function(compressor){
|
2286
|
+
def(AST_Sequence, function(compressor) {
|
2275
2287
|
return this.tail_node().is_number(compressor);
|
2276
2288
|
});
|
2277
|
-
def(AST_Conditional, function(compressor){
|
2289
|
+
def(AST_Conditional, function(compressor) {
|
2278
2290
|
return this.consequent.is_number(compressor) && this.alternative.is_number(compressor);
|
2279
2291
|
});
|
2280
|
-
})(function(node, func){
|
2292
|
+
})(function(node, func) {
|
2281
2293
|
node.DEFMETHOD("is_number", func);
|
2282
2294
|
});
|
2283
2295
|
|
2284
2296
|
// methods to determine if an expression has a string result type
|
2285
|
-
(function(def){
|
2297
|
+
(function(def) {
|
2286
2298
|
def(AST_Node, return_false);
|
2287
2299
|
def(AST_String, return_true);
|
2288
|
-
def(AST_TemplateString, function(){
|
2300
|
+
def(AST_TemplateString, function() {
|
2289
2301
|
return this.segments.length === 1;
|
2290
2302
|
});
|
2291
|
-
def(AST_UnaryPrefix, function(){
|
2303
|
+
def(AST_UnaryPrefix, function() {
|
2292
2304
|
return this.operator == "typeof";
|
2293
2305
|
});
|
2294
|
-
def(AST_Binary, function(compressor){
|
2306
|
+
def(AST_Binary, function(compressor) {
|
2295
2307
|
return this.operator == "+" &&
|
2296
2308
|
(this.left.is_string(compressor) || this.right.is_string(compressor));
|
2297
2309
|
});
|
2298
|
-
def(AST_Assign, function(compressor){
|
2310
|
+
def(AST_Assign, function(compressor) {
|
2299
2311
|
return (this.operator == "=" || this.operator == "+=") && this.right.is_string(compressor);
|
2300
2312
|
});
|
2301
|
-
def(AST_Sequence, function(compressor){
|
2313
|
+
def(AST_Sequence, function(compressor) {
|
2302
2314
|
return this.tail_node().is_string(compressor);
|
2303
2315
|
});
|
2304
|
-
def(AST_Conditional, function(compressor){
|
2316
|
+
def(AST_Conditional, function(compressor) {
|
2305
2317
|
return this.consequent.is_string(compressor) && this.alternative.is_string(compressor);
|
2306
2318
|
});
|
2307
|
-
})(function(node, func){
|
2319
|
+
})(function(node, func) {
|
2308
2320
|
node.DEFMETHOD("is_string", func);
|
2309
2321
|
});
|
2310
2322
|
|
@@ -2316,7 +2328,7 @@ merge(Compressor.prototype, {
|
|
2316
2328
|
if (parent instanceof AST_Assign && parent.left === node) return node;
|
2317
2329
|
}
|
2318
2330
|
|
2319
|
-
(function(def){
|
2331
|
+
(function(def) {
|
2320
2332
|
AST_Node.DEFMETHOD("resolve_defines", function(compressor) {
|
2321
2333
|
if (!compressor.option("global_defs")) return;
|
2322
2334
|
var def = this._find_defs(compressor, "");
|
@@ -2327,7 +2339,7 @@ merge(Compressor.prototype, {
|
|
2327
2339
|
parent = compressor.parent(level++);
|
2328
2340
|
} while (parent instanceof AST_PropAccess && parent.expression === node);
|
2329
2341
|
if (is_lhs(node, parent)) {
|
2330
|
-
compressor.warn(
|
2342
|
+
compressor.warn("global_defs " + this.print_to_string() + " redefined [{file}:{line},{col}]", this.start);
|
2331
2343
|
} else {
|
2332
2344
|
return def;
|
2333
2345
|
}
|
@@ -2355,10 +2367,10 @@ merge(Compressor.prototype, {
|
|
2355
2367
|
return make_node_from_constant(value, orig);
|
2356
2368
|
}
|
2357
2369
|
def(AST_Node, noop);
|
2358
|
-
def(AST_Dot, function(compressor, suffix){
|
2370
|
+
def(AST_Dot, function(compressor, suffix) {
|
2359
2371
|
return this.expression._find_defs(compressor, "." + this.property + suffix);
|
2360
2372
|
});
|
2361
|
-
def(AST_SymbolRef, function(compressor, suffix){
|
2373
|
+
def(AST_SymbolRef, function(compressor, suffix) {
|
2362
2374
|
if (!this.global()) return;
|
2363
2375
|
var name;
|
2364
2376
|
var defines = compressor.option("global_defs");
|
@@ -2374,7 +2386,7 @@ merge(Compressor.prototype, {
|
|
2374
2386
|
return node;
|
2375
2387
|
}
|
2376
2388
|
});
|
2377
|
-
})(function(node, func){
|
2389
|
+
})(function(node, func) {
|
2378
2390
|
node.DEFMETHOD("_find_defs", func);
|
2379
2391
|
});
|
2380
2392
|
|
@@ -2489,13 +2501,13 @@ merge(Compressor.prototype, {
|
|
2489
2501
|
convert_to_predicate(static_fns);
|
2490
2502
|
|
2491
2503
|
// methods to evaluate a constant expression
|
2492
|
-
(function(def){
|
2504
|
+
(function(def) {
|
2493
2505
|
// If the node has been successfully reduced to a constant,
|
2494
2506
|
// then its value is returned; otherwise the element itself
|
2495
2507
|
// is returned.
|
2496
2508
|
// They can be distinguished as constant value is never a
|
2497
2509
|
// descendant of AST_Node.
|
2498
|
-
AST_Node.DEFMETHOD("evaluate", function(compressor){
|
2510
|
+
AST_Node.DEFMETHOD("evaluate", function(compressor) {
|
2499
2511
|
if (!compressor.option("evaluate")) return this;
|
2500
2512
|
var val = this._eval(compressor, 1);
|
2501
2513
|
if (!val || val instanceof RegExp) return val;
|
@@ -2503,7 +2515,7 @@ merge(Compressor.prototype, {
|
|
2503
2515
|
return val;
|
2504
2516
|
});
|
2505
2517
|
var unaryPrefix = makePredicate("! ~ - + void");
|
2506
|
-
AST_Node.DEFMETHOD("is_constant", function(){
|
2518
|
+
AST_Node.DEFMETHOD("is_constant", function() {
|
2507
2519
|
// Accomodate when compress option evaluate=false
|
2508
2520
|
// as well as the common constant expressions !0 and -1
|
2509
2521
|
if (this instanceof AST_Constant) {
|
@@ -2514,13 +2526,13 @@ merge(Compressor.prototype, {
|
|
2514
2526
|
&& unaryPrefix(this.operator);
|
2515
2527
|
}
|
2516
2528
|
});
|
2517
|
-
def(AST_Statement, function(){
|
2529
|
+
def(AST_Statement, function() {
|
2518
2530
|
throw new Error(string_template("Cannot evaluate a statement [{file}:{line},{col}]", this.start));
|
2519
2531
|
});
|
2520
2532
|
def(AST_Lambda, return_this);
|
2521
2533
|
def(AST_Class, return_this);
|
2522
2534
|
def(AST_Node, return_this);
|
2523
|
-
def(AST_Constant, function(){
|
2535
|
+
def(AST_Constant, function() {
|
2524
2536
|
return this.getValue();
|
2525
2537
|
});
|
2526
2538
|
def(AST_TemplateString, function() {
|
@@ -2564,7 +2576,7 @@ merge(Compressor.prototype, {
|
|
2564
2576
|
key = key._eval(compressor, depth);
|
2565
2577
|
if (key === prop.key) return this;
|
2566
2578
|
}
|
2567
|
-
if (typeof Object.prototype[key] ===
|
2579
|
+
if (typeof Object.prototype[key] === "function") {
|
2568
2580
|
return this;
|
2569
2581
|
}
|
2570
2582
|
if (prop.value instanceof AST_Function) continue;
|
@@ -2585,7 +2597,7 @@ merge(Compressor.prototype, {
|
|
2585
2597
|
&& (e instanceof AST_Lambda
|
2586
2598
|
|| e instanceof AST_SymbolRef
|
2587
2599
|
&& e.fixed_value() instanceof AST_Lambda)) {
|
2588
|
-
return typeof function(){};
|
2600
|
+
return typeof function() {};
|
2589
2601
|
}
|
2590
2602
|
if (!non_converting_unary(this.operator)) depth++;
|
2591
2603
|
e = e._eval(compressor, depth);
|
@@ -2765,12 +2777,12 @@ merge(Compressor.prototype, {
|
|
2765
2777
|
return this;
|
2766
2778
|
});
|
2767
2779
|
def(AST_New, return_this);
|
2768
|
-
})(function(node, func){
|
2780
|
+
})(function(node, func) {
|
2769
2781
|
node.DEFMETHOD("_eval", func);
|
2770
2782
|
});
|
2771
2783
|
|
2772
2784
|
// method to negate an expression
|
2773
|
-
(function(def){
|
2785
|
+
(function(def) {
|
2774
2786
|
function basic_negation(exp) {
|
2775
2787
|
return make_node(AST_UnaryPrefix, exp, {
|
2776
2788
|
operator: "!",
|
@@ -2787,35 +2799,35 @@ merge(Compressor.prototype, {
|
|
2787
2799
|
}
|
2788
2800
|
return best_of_expression(negated, alt);
|
2789
2801
|
}
|
2790
|
-
def(AST_Node, function(){
|
2802
|
+
def(AST_Node, function() {
|
2791
2803
|
return basic_negation(this);
|
2792
2804
|
});
|
2793
|
-
def(AST_Statement, function(){
|
2805
|
+
def(AST_Statement, function() {
|
2794
2806
|
throw new Error("Cannot negate a statement");
|
2795
2807
|
});
|
2796
|
-
def(AST_Function, function(){
|
2808
|
+
def(AST_Function, function() {
|
2797
2809
|
return basic_negation(this);
|
2798
2810
|
});
|
2799
|
-
def(AST_Arrow, function(){
|
2811
|
+
def(AST_Arrow, function() {
|
2800
2812
|
return basic_negation(this);
|
2801
2813
|
});
|
2802
|
-
def(AST_UnaryPrefix, function(){
|
2814
|
+
def(AST_UnaryPrefix, function() {
|
2803
2815
|
if (this.operator == "!")
|
2804
2816
|
return this.expression;
|
2805
2817
|
return basic_negation(this);
|
2806
2818
|
});
|
2807
|
-
def(AST_Sequence, function(compressor){
|
2819
|
+
def(AST_Sequence, function(compressor) {
|
2808
2820
|
var expressions = this.expressions.slice();
|
2809
2821
|
expressions.push(expressions.pop().negate(compressor));
|
2810
2822
|
return make_sequence(this, expressions);
|
2811
2823
|
});
|
2812
|
-
def(AST_Conditional, function(compressor, first_in_statement){
|
2824
|
+
def(AST_Conditional, function(compressor, first_in_statement) {
|
2813
2825
|
var self = this.clone();
|
2814
2826
|
self.consequent = self.consequent.negate(compressor);
|
2815
2827
|
self.alternative = self.alternative.negate(compressor);
|
2816
2828
|
return best(this, self, first_in_statement);
|
2817
2829
|
});
|
2818
|
-
def(AST_Binary, function(compressor, first_in_statement){
|
2830
|
+
def(AST_Binary, function(compressor, first_in_statement) {
|
2819
2831
|
var self = this.clone(), op = this.operator;
|
2820
2832
|
if (compressor.option("unsafe_comps")) {
|
2821
2833
|
switch (op) {
|
@@ -2843,8 +2855,8 @@ merge(Compressor.prototype, {
|
|
2843
2855
|
}
|
2844
2856
|
return basic_negation(this);
|
2845
2857
|
});
|
2846
|
-
})(function(node, func){
|
2847
|
-
node.DEFMETHOD("negate", function(compressor, first_in_statement){
|
2858
|
+
})(function(node, func) {
|
2859
|
+
node.DEFMETHOD("negate", function(compressor, first_in_statement) {
|
2848
2860
|
return func.call(this, compressor, first_in_statement);
|
2849
2861
|
});
|
2850
2862
|
});
|
@@ -2884,7 +2896,7 @@ merge(Compressor.prototype, {
|
|
2884
2896
|
});
|
2885
2897
|
|
2886
2898
|
// determine if expression has side effects
|
2887
|
-
(function(def){
|
2899
|
+
(function(def) {
|
2888
2900
|
def(AST_Node, return_true);
|
2889
2901
|
|
2890
2902
|
def(AST_EmptyStatement, return_false);
|
@@ -2898,10 +2910,10 @@ merge(Compressor.prototype, {
|
|
2898
2910
|
return false;
|
2899
2911
|
}
|
2900
2912
|
|
2901
|
-
def(AST_Block, function(compressor){
|
2913
|
+
def(AST_Block, function(compressor) {
|
2902
2914
|
return any(this.body, compressor);
|
2903
2915
|
});
|
2904
|
-
def(AST_Call, function(compressor){
|
2916
|
+
def(AST_Call, function(compressor) {
|
2905
2917
|
if (!this.is_expr_pure(compressor)
|
2906
2918
|
&& (!this.expression.is_call_pure(compressor)
|
2907
2919
|
|| this.expression.has_side_effects(compressor))) {
|
@@ -2909,91 +2921,91 @@ merge(Compressor.prototype, {
|
|
2909
2921
|
}
|
2910
2922
|
return any(this.args, compressor);
|
2911
2923
|
});
|
2912
|
-
def(AST_Switch, function(compressor){
|
2924
|
+
def(AST_Switch, function(compressor) {
|
2913
2925
|
return this.expression.has_side_effects(compressor)
|
2914
2926
|
|| any(this.body, compressor);
|
2915
2927
|
});
|
2916
|
-
def(AST_Case, function(compressor){
|
2928
|
+
def(AST_Case, function(compressor) {
|
2917
2929
|
return this.expression.has_side_effects(compressor)
|
2918
2930
|
|| any(this.body, compressor);
|
2919
2931
|
});
|
2920
|
-
def(AST_Try, function(compressor){
|
2932
|
+
def(AST_Try, function(compressor) {
|
2921
2933
|
return any(this.body, compressor)
|
2922
2934
|
|| this.bcatch && this.bcatch.has_side_effects(compressor)
|
2923
2935
|
|| this.bfinally && this.bfinally.has_side_effects(compressor);
|
2924
2936
|
});
|
2925
|
-
def(AST_If, function(compressor){
|
2937
|
+
def(AST_If, function(compressor) {
|
2926
2938
|
return this.condition.has_side_effects(compressor)
|
2927
2939
|
|| this.body && this.body.has_side_effects(compressor)
|
2928
2940
|
|| this.alternative && this.alternative.has_side_effects(compressor);
|
2929
2941
|
});
|
2930
|
-
def(AST_LabeledStatement, function(compressor){
|
2942
|
+
def(AST_LabeledStatement, function(compressor) {
|
2931
2943
|
return this.body.has_side_effects(compressor);
|
2932
2944
|
});
|
2933
|
-
def(AST_SimpleStatement, function(compressor){
|
2945
|
+
def(AST_SimpleStatement, function(compressor) {
|
2934
2946
|
return this.body.has_side_effects(compressor);
|
2935
2947
|
});
|
2936
2948
|
def(AST_Lambda, return_false);
|
2937
2949
|
def(AST_Class, return_false);
|
2938
2950
|
def(AST_DefClass, return_true);
|
2939
|
-
def(AST_Binary, function(compressor){
|
2951
|
+
def(AST_Binary, function(compressor) {
|
2940
2952
|
return this.left.has_side_effects(compressor)
|
2941
2953
|
|| this.right.has_side_effects(compressor);
|
2942
2954
|
});
|
2943
2955
|
def(AST_Assign, return_true);
|
2944
|
-
def(AST_Conditional, function(compressor){
|
2956
|
+
def(AST_Conditional, function(compressor) {
|
2945
2957
|
return this.condition.has_side_effects(compressor)
|
2946
2958
|
|| this.consequent.has_side_effects(compressor)
|
2947
2959
|
|| this.alternative.has_side_effects(compressor);
|
2948
2960
|
});
|
2949
|
-
def(AST_Unary, function(compressor){
|
2961
|
+
def(AST_Unary, function(compressor) {
|
2950
2962
|
return unary_side_effects(this.operator)
|
2951
2963
|
|| this.expression.has_side_effects(compressor);
|
2952
2964
|
});
|
2953
|
-
def(AST_SymbolRef, function(compressor){
|
2965
|
+
def(AST_SymbolRef, function(compressor) {
|
2954
2966
|
return !this.is_declared(compressor);
|
2955
2967
|
});
|
2956
2968
|
def(AST_SymbolDeclaration, return_false);
|
2957
|
-
def(AST_Object, function(compressor){
|
2969
|
+
def(AST_Object, function(compressor) {
|
2958
2970
|
return any(this.properties, compressor);
|
2959
2971
|
});
|
2960
|
-
def(AST_ObjectProperty, function(compressor){
|
2972
|
+
def(AST_ObjectProperty, function(compressor) {
|
2961
2973
|
if (this.key instanceof AST_ObjectKeyVal &&
|
2962
2974
|
this.key.has_side_effects(compressor))
|
2963
2975
|
return true;
|
2964
2976
|
return this.value.has_side_effects(compressor);
|
2965
2977
|
});
|
2966
|
-
def(AST_Array, function(compressor){
|
2978
|
+
def(AST_Array, function(compressor) {
|
2967
2979
|
return any(this.elements, compressor);
|
2968
2980
|
});
|
2969
|
-
def(AST_Dot, function(compressor){
|
2981
|
+
def(AST_Dot, function(compressor) {
|
2970
2982
|
return this.expression.may_throw_on_access(compressor)
|
2971
2983
|
|| this.expression.has_side_effects(compressor);
|
2972
2984
|
});
|
2973
|
-
def(AST_Sub, function(compressor){
|
2985
|
+
def(AST_Sub, function(compressor) {
|
2974
2986
|
return this.expression.may_throw_on_access(compressor)
|
2975
2987
|
|| this.expression.has_side_effects(compressor)
|
2976
2988
|
|| this.property.has_side_effects(compressor);
|
2977
2989
|
});
|
2978
|
-
def(AST_Sequence, function(compressor){
|
2990
|
+
def(AST_Sequence, function(compressor) {
|
2979
2991
|
return any(this.expressions, compressor);
|
2980
2992
|
});
|
2981
|
-
def(AST_Definitions, function(compressor){
|
2993
|
+
def(AST_Definitions, function(compressor) {
|
2982
2994
|
return any(this.definitions, compressor);
|
2983
2995
|
});
|
2984
|
-
def(AST_VarDef, function(compressor){
|
2996
|
+
def(AST_VarDef, function(compressor) {
|
2985
2997
|
return this.value;
|
2986
2998
|
});
|
2987
2999
|
def(AST_TemplateSegment, return_false);
|
2988
|
-
def(AST_TemplateString, function(compressor){
|
3000
|
+
def(AST_TemplateString, function(compressor) {
|
2989
3001
|
return any(this.segments, compressor);
|
2990
3002
|
});
|
2991
|
-
})(function(node, func){
|
3003
|
+
})(function(node, func) {
|
2992
3004
|
node.DEFMETHOD("has_side_effects", func);
|
2993
3005
|
});
|
2994
3006
|
|
2995
3007
|
// determine if expression may throw
|
2996
|
-
(function(def){
|
3008
|
+
(function(def) {
|
2997
3009
|
def(AST_Node, return_true);
|
2998
3010
|
|
2999
3011
|
def(AST_Class, return_false);
|
@@ -3010,10 +3022,10 @@ merge(Compressor.prototype, {
|
|
3010
3022
|
return false;
|
3011
3023
|
}
|
3012
3024
|
|
3013
|
-
def(AST_Array, function(compressor){
|
3025
|
+
def(AST_Array, function(compressor) {
|
3014
3026
|
return any(this.elements, compressor);
|
3015
3027
|
});
|
3016
|
-
def(AST_Assign, function(compressor){
|
3028
|
+
def(AST_Assign, function(compressor) {
|
3017
3029
|
if (this.right.may_throw(compressor)) return true;
|
3018
3030
|
if (!compressor.has_directive("use strict")
|
3019
3031
|
&& this.operator == "="
|
@@ -3022,90 +3034,90 @@ merge(Compressor.prototype, {
|
|
3022
3034
|
}
|
3023
3035
|
return this.left.may_throw(compressor);
|
3024
3036
|
});
|
3025
|
-
def(AST_Binary, function(compressor){
|
3037
|
+
def(AST_Binary, function(compressor) {
|
3026
3038
|
return this.left.may_throw(compressor)
|
3027
3039
|
|| this.right.may_throw(compressor);
|
3028
3040
|
});
|
3029
|
-
def(AST_Block, function(compressor){
|
3041
|
+
def(AST_Block, function(compressor) {
|
3030
3042
|
return any(this.body, compressor);
|
3031
3043
|
});
|
3032
|
-
def(AST_Call, function(compressor){
|
3044
|
+
def(AST_Call, function(compressor) {
|
3033
3045
|
if (any(this.args, compressor)) return true;
|
3034
3046
|
if (this.is_expr_pure(compressor)) return false;
|
3035
3047
|
if (this.expression.may_throw(compressor)) return true;
|
3036
3048
|
return !(this.expression instanceof AST_Lambda)
|
3037
3049
|
|| any(this.expression.body, compressor);
|
3038
3050
|
});
|
3039
|
-
def(AST_Case, function(compressor){
|
3051
|
+
def(AST_Case, function(compressor) {
|
3040
3052
|
return this.expression.may_throw(compressor)
|
3041
3053
|
|| any(this.body, compressor);
|
3042
3054
|
});
|
3043
|
-
def(AST_Conditional, function(compressor){
|
3055
|
+
def(AST_Conditional, function(compressor) {
|
3044
3056
|
return this.condition.may_throw(compressor)
|
3045
3057
|
|| this.consequent.may_throw(compressor)
|
3046
3058
|
|| this.alternative.may_throw(compressor);
|
3047
3059
|
});
|
3048
|
-
def(AST_Definitions, function(compressor){
|
3060
|
+
def(AST_Definitions, function(compressor) {
|
3049
3061
|
return any(this.definitions, compressor);
|
3050
3062
|
});
|
3051
|
-
def(AST_Dot, function(compressor){
|
3063
|
+
def(AST_Dot, function(compressor) {
|
3052
3064
|
return this.expression.may_throw_on_access(compressor)
|
3053
3065
|
|| this.expression.may_throw(compressor);
|
3054
3066
|
});
|
3055
|
-
def(AST_If, function(compressor){
|
3067
|
+
def(AST_If, function(compressor) {
|
3056
3068
|
return this.condition.may_throw(compressor)
|
3057
3069
|
|| this.body && this.body.may_throw(compressor)
|
3058
3070
|
|| this.alternative && this.alternative.may_throw(compressor);
|
3059
3071
|
});
|
3060
|
-
def(AST_LabeledStatement, function(compressor){
|
3072
|
+
def(AST_LabeledStatement, function(compressor) {
|
3061
3073
|
return this.body.may_throw(compressor);
|
3062
3074
|
});
|
3063
|
-
def(AST_Object, function(compressor){
|
3075
|
+
def(AST_Object, function(compressor) {
|
3064
3076
|
return any(this.properties, compressor);
|
3065
3077
|
});
|
3066
|
-
def(AST_ObjectProperty, function(compressor){
|
3078
|
+
def(AST_ObjectProperty, function(compressor) {
|
3067
3079
|
return this.value.may_throw(compressor);
|
3068
3080
|
});
|
3069
|
-
def(AST_Return, function(compressor){
|
3081
|
+
def(AST_Return, function(compressor) {
|
3070
3082
|
return this.value && this.value.may_throw(compressor);
|
3071
3083
|
});
|
3072
|
-
def(AST_Sequence, function(compressor){
|
3084
|
+
def(AST_Sequence, function(compressor) {
|
3073
3085
|
return any(this.expressions, compressor);
|
3074
3086
|
});
|
3075
|
-
def(AST_SimpleStatement, function(compressor){
|
3087
|
+
def(AST_SimpleStatement, function(compressor) {
|
3076
3088
|
return this.body.may_throw(compressor);
|
3077
3089
|
});
|
3078
|
-
def(AST_Sub, function(compressor){
|
3090
|
+
def(AST_Sub, function(compressor) {
|
3079
3091
|
return this.expression.may_throw_on_access(compressor)
|
3080
3092
|
|| this.expression.may_throw(compressor)
|
3081
3093
|
|| this.property.may_throw(compressor);
|
3082
3094
|
});
|
3083
|
-
def(AST_Switch, function(compressor){
|
3095
|
+
def(AST_Switch, function(compressor) {
|
3084
3096
|
return this.expression.may_throw(compressor)
|
3085
3097
|
|| any(this.body, compressor);
|
3086
3098
|
});
|
3087
|
-
def(AST_SymbolRef, function(compressor){
|
3099
|
+
def(AST_SymbolRef, function(compressor) {
|
3088
3100
|
return !this.is_declared(compressor);
|
3089
3101
|
});
|
3090
|
-
def(AST_Try, function(compressor){
|
3102
|
+
def(AST_Try, function(compressor) {
|
3091
3103
|
return this.bcatch ? this.bcatch.may_throw(compressor) : any(this.body, compressor)
|
3092
3104
|
|| this.bfinally && this.bfinally.may_throw(compressor);
|
3093
3105
|
});
|
3094
|
-
def(AST_Unary, function(compressor){
|
3106
|
+
def(AST_Unary, function(compressor) {
|
3095
3107
|
if (this.operator == "typeof" && this.expression instanceof AST_SymbolRef)
|
3096
3108
|
return false;
|
3097
3109
|
return this.expression.may_throw(compressor);
|
3098
3110
|
});
|
3099
|
-
def(AST_VarDef, function(compressor){
|
3111
|
+
def(AST_VarDef, function(compressor) {
|
3100
3112
|
if (!this.value) return false;
|
3101
3113
|
return this.value.may_throw(compressor);
|
3102
3114
|
});
|
3103
|
-
})(function(node, func){
|
3115
|
+
})(function(node, func) {
|
3104
3116
|
node.DEFMETHOD("may_throw", func);
|
3105
3117
|
});
|
3106
3118
|
|
3107
3119
|
// determine if expression is constant
|
3108
|
-
(function(def){
|
3120
|
+
(function(def) {
|
3109
3121
|
function all(list) {
|
3110
3122
|
for (var i = list.length; --i >= 0;)
|
3111
3123
|
if (!list[i].is_constant_expression())
|
@@ -3147,68 +3159,76 @@ merge(Compressor.prototype, {
|
|
3147
3159
|
|
3148
3160
|
def(AST_Node, return_false);
|
3149
3161
|
def(AST_Constant, return_true);
|
3150
|
-
def(AST_Class,
|
3162
|
+
def(AST_Class, function(scope) {
|
3163
|
+
var self = this;
|
3164
|
+
if (self.extends && !self.extends.is_constant_expression(scope)) {
|
3165
|
+
return false;
|
3166
|
+
}
|
3167
|
+
return all_refs_local.call(self, scope);
|
3168
|
+
});
|
3151
3169
|
def(AST_Lambda, all_refs_local);
|
3152
|
-
def(AST_Unary, function(){
|
3170
|
+
def(AST_Unary, function() {
|
3153
3171
|
return this.expression.is_constant_expression();
|
3154
3172
|
});
|
3155
|
-
def(AST_Binary, function(){
|
3173
|
+
def(AST_Binary, function() {
|
3156
3174
|
return this.left.is_constant_expression() && this.right.is_constant_expression();
|
3157
3175
|
});
|
3158
|
-
def(AST_Array, function(){
|
3176
|
+
def(AST_Array, function() {
|
3159
3177
|
return all(this.elements);
|
3160
3178
|
});
|
3161
|
-
def(AST_Object, function(){
|
3179
|
+
def(AST_Object, function() {
|
3162
3180
|
return all(this.properties);
|
3163
3181
|
});
|
3164
|
-
def(AST_ObjectProperty, function(){
|
3182
|
+
def(AST_ObjectProperty, function() {
|
3165
3183
|
return !(this.key instanceof AST_Node) && this.value.is_constant_expression();
|
3166
3184
|
});
|
3167
|
-
})(function(node, func){
|
3185
|
+
})(function(node, func) {
|
3168
3186
|
node.DEFMETHOD("is_constant_expression", func);
|
3169
3187
|
});
|
3170
3188
|
|
3171
3189
|
// tell me if a statement aborts
|
3172
3190
|
function aborts(thing) {
|
3173
3191
|
return thing && thing.aborts();
|
3174
|
-
}
|
3175
|
-
(function(def){
|
3192
|
+
}
|
3193
|
+
(function(def) {
|
3176
3194
|
def(AST_Statement, return_null);
|
3177
3195
|
def(AST_Jump, return_this);
|
3178
|
-
function block_aborts(){
|
3196
|
+
function block_aborts() {
|
3179
3197
|
for (var i = 0; i < this.body.length; i++) {
|
3180
3198
|
if (aborts(this.body[i])) {
|
3181
3199
|
return this.body[i];
|
3182
3200
|
}
|
3183
3201
|
}
|
3184
3202
|
return null;
|
3185
|
-
}
|
3186
|
-
def(AST_Import, function(){ return null; });
|
3203
|
+
}
|
3204
|
+
def(AST_Import, function() { return null; });
|
3187
3205
|
def(AST_BlockStatement, block_aborts);
|
3188
3206
|
def(AST_SwitchBranch, block_aborts);
|
3189
|
-
def(AST_If, function(){
|
3207
|
+
def(AST_If, function() {
|
3190
3208
|
return this.alternative && aborts(this.body) && aborts(this.alternative) && this;
|
3191
3209
|
});
|
3192
|
-
})(function(node, func){
|
3210
|
+
})(function(node, func) {
|
3193
3211
|
node.DEFMETHOD("aborts", func);
|
3194
3212
|
});
|
3195
3213
|
|
3196
3214
|
/* -----[ optimizers ]----- */
|
3197
3215
|
|
3198
|
-
|
3199
|
-
|
3216
|
+
var directives = ["use asm", "use strict"];
|
3217
|
+
OPT(AST_Directive, function(self, compressor) {
|
3218
|
+
if (compressor.option("directives")
|
3219
|
+
&& (!member(self.value, directives) || compressor.has_directive(self.value) !== self)) {
|
3200
3220
|
return make_node(AST_EmptyStatement, self);
|
3201
3221
|
}
|
3202
3222
|
return self;
|
3203
3223
|
});
|
3204
3224
|
|
3205
|
-
OPT(AST_Debugger, function(self, compressor){
|
3225
|
+
OPT(AST_Debugger, function(self, compressor) {
|
3206
3226
|
if (compressor.option("drop_debugger"))
|
3207
3227
|
return make_node(AST_EmptyStatement, self);
|
3208
3228
|
return self;
|
3209
3229
|
});
|
3210
3230
|
|
3211
|
-
OPT(AST_LabeledStatement, function(self, compressor){
|
3231
|
+
OPT(AST_LabeledStatement, function(self, compressor) {
|
3212
3232
|
if (self.body instanceof AST_Break
|
3213
3233
|
&& compressor.loopcontrol_target(self.body) === self.body) {
|
3214
3234
|
return make_node(AST_EmptyStatement, self);
|
@@ -3216,7 +3236,7 @@ merge(Compressor.prototype, {
|
|
3216
3236
|
return self.label.references.length == 0 ? self.body : self;
|
3217
3237
|
});
|
3218
3238
|
|
3219
|
-
OPT(AST_Block, function(self, compressor){
|
3239
|
+
OPT(AST_Block, function(self, compressor) {
|
3220
3240
|
tighten_body(self.body, compressor);
|
3221
3241
|
return self;
|
3222
3242
|
});
|
@@ -3229,7 +3249,7 @@ merge(Compressor.prototype, {
|
|
3229
3249
|
);
|
3230
3250
|
}
|
3231
3251
|
|
3232
|
-
OPT(AST_BlockStatement, function(self, compressor){
|
3252
|
+
OPT(AST_BlockStatement, function(self, compressor) {
|
3233
3253
|
tighten_body(self.body, compressor);
|
3234
3254
|
switch (self.body.length) {
|
3235
3255
|
case 1:
|
@@ -3256,7 +3276,7 @@ merge(Compressor.prototype, {
|
|
3256
3276
|
}
|
3257
3277
|
OPT(AST_Lambda, opt_AST_Lambda);
|
3258
3278
|
|
3259
|
-
AST_Scope.DEFMETHOD("drop_unused", function(compressor){
|
3279
|
+
AST_Scope.DEFMETHOD("drop_unused", function(compressor) {
|
3260
3280
|
if (!compressor.option("unused")) return;
|
3261
3281
|
if (compressor.has_directive("use asm")) return;
|
3262
3282
|
var self = this;
|
@@ -3286,7 +3306,17 @@ merge(Compressor.prototype, {
|
|
3286
3306
|
// pass 1: find out which symbols are directly used in
|
3287
3307
|
// this scope (not in nested scopes).
|
3288
3308
|
var scope = this;
|
3289
|
-
var tw = new TreeWalker(function(node, descend){
|
3309
|
+
var tw = new TreeWalker(function(node, descend) {
|
3310
|
+
if (node instanceof AST_Lambda && node.uses_arguments && !tw.has_directive("use strict")) {
|
3311
|
+
node.argnames.forEach(function(argname) {
|
3312
|
+
if (!(argname instanceof AST_SymbolDeclaration)) return;
|
3313
|
+
var def = argname.definition();
|
3314
|
+
if (!(def.id in in_use_ids)) {
|
3315
|
+
in_use_ids[def.id] = true;
|
3316
|
+
in_use.push(def);
|
3317
|
+
}
|
3318
|
+
});
|
3319
|
+
}
|
3290
3320
|
if (node === self) return;
|
3291
3321
|
if (node instanceof AST_Defun || node instanceof AST_DefClass) {
|
3292
3322
|
var node_def = node.name.definition();
|
@@ -3305,7 +3335,7 @@ merge(Compressor.prototype, {
|
|
3305
3335
|
}
|
3306
3336
|
if (node instanceof AST_Definitions && scope === self) {
|
3307
3337
|
var in_export = tw.parent() instanceof AST_Export;
|
3308
|
-
node.definitions.forEach(function(def){
|
3338
|
+
node.definitions.forEach(function(def) {
|
3309
3339
|
if (def.name instanceof AST_SymbolVar) {
|
3310
3340
|
var_defs_by_id.add(def.name.definition().id, def);
|
3311
3341
|
}
|
@@ -3327,7 +3357,7 @@ merge(Compressor.prototype, {
|
|
3327
3357
|
def.walk(tw);
|
3328
3358
|
destructuring_value = destructuring_cache;
|
3329
3359
|
} else {
|
3330
|
-
var node_def = def.name.definition()
|
3360
|
+
var node_def = def.name.definition();
|
3331
3361
|
initializations.add(node_def.id, def.value);
|
3332
3362
|
if (!node_def.chained && def.name.fixed_value() === def.value) {
|
3333
3363
|
fixed_ids[node_def.id] = def;
|
@@ -3382,8 +3412,7 @@ merge(Compressor.prototype, {
|
|
3382
3412
|
// any declarations with same name will overshadow
|
3383
3413
|
// name of this anonymous function and can therefore
|
3384
3414
|
// never be used anywhere
|
3385
|
-
if (!(def.id in in_use_ids) || def.orig.length > 1)
|
3386
|
-
node.name = null;
|
3415
|
+
if (!(def.id in in_use_ids) || def.orig.length > 1) node.name = null;
|
3387
3416
|
}
|
3388
3417
|
if (node instanceof AST_Lambda && !(node instanceof AST_Accessor)) {
|
3389
3418
|
var trim = !compressor.option("keep_fargs");
|
@@ -3406,8 +3435,7 @@ merge(Compressor.prototype, {
|
|
3406
3435
|
a.pop();
|
3407
3436
|
compressor[sym.unreferenced() ? "warn" : "info"]("Dropping unused function argument {name} [{file}:{line},{col}]", template(sym));
|
3408
3437
|
}
|
3409
|
-
}
|
3410
|
-
else {
|
3438
|
+
} else {
|
3411
3439
|
trim = false;
|
3412
3440
|
}
|
3413
3441
|
}
|
@@ -3605,7 +3633,7 @@ merge(Compressor.prototype, {
|
|
3605
3633
|
}
|
3606
3634
|
});
|
3607
3635
|
|
3608
|
-
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
|
3636
|
+
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor) {
|
3609
3637
|
var self = this;
|
3610
3638
|
if (compressor.has_directive("use asm")) return self;
|
3611
3639
|
// Hoisting makes no sense in an arrow func
|
@@ -3620,7 +3648,7 @@ merge(Compressor.prototype, {
|
|
3620
3648
|
var vars = new Dictionary(), vars_found = 0, var_decl = 0;
|
3621
3649
|
// let's count var_decl first, we seem to waste a lot of
|
3622
3650
|
// space if we hoist `var` when there's only one.
|
3623
|
-
self.walk(new TreeWalker(function(node){
|
3651
|
+
self.walk(new TreeWalker(function(node) {
|
3624
3652
|
if (node instanceof AST_Scope && node !== self)
|
3625
3653
|
return true;
|
3626
3654
|
if (node instanceof AST_Var) {
|
@@ -3643,7 +3671,7 @@ merge(Compressor.prototype, {
|
|
3643
3671
|
return make_node(AST_EmptyStatement, node);
|
3644
3672
|
}
|
3645
3673
|
if (hoist_vars && node instanceof AST_Var) {
|
3646
|
-
node.definitions.forEach(function(def){
|
3674
|
+
node.definitions.forEach(function(def) {
|
3647
3675
|
if (def.name instanceof AST_Destructuring) return;
|
3648
3676
|
vars.set(def.name.name, def);
|
3649
3677
|
++vars_found;
|
@@ -3674,9 +3702,9 @@ merge(Compressor.prototype, {
|
|
3674
3702
|
if (vars_found > 0) {
|
3675
3703
|
// collect only vars which don't show up in self's arguments list
|
3676
3704
|
var defs = [];
|
3677
|
-
vars.each(function(def, name){
|
3705
|
+
vars.each(function(def, name) {
|
3678
3706
|
if (self instanceof AST_Lambda
|
3679
|
-
&& find_if(function(x){ return x.name == def.name.name },
|
3707
|
+
&& find_if(function(x) { return x.name == def.name.name; },
|
3680
3708
|
self.args_as_names())) {
|
3681
3709
|
vars.del(name);
|
3682
3710
|
} else {
|
@@ -3734,7 +3762,7 @@ merge(Compressor.prototype, {
|
|
3734
3762
|
definitions: defs
|
3735
3763
|
});
|
3736
3764
|
hoisted.push(defs);
|
3737
|
-
}
|
3765
|
+
}
|
3738
3766
|
}
|
3739
3767
|
self.body = dirs.concat(hoisted, self.body);
|
3740
3768
|
}
|
@@ -3764,7 +3792,7 @@ merge(Compressor.prototype, {
|
|
3764
3792
|
return name;
|
3765
3793
|
});
|
3766
3794
|
|
3767
|
-
AST_Scope.DEFMETHOD("hoist_properties", function(compressor){
|
3795
|
+
AST_Scope.DEFMETHOD("hoist_properties", function(compressor) {
|
3768
3796
|
var self = this;
|
3769
3797
|
if (!compressor.option("hoist_props") || compressor.has_directive("use asm")) return self;
|
3770
3798
|
var top_retain = self instanceof AST_Toplevel && compressor.top_retain || return_false;
|
@@ -3825,7 +3853,7 @@ merge(Compressor.prototype, {
|
|
3825
3853
|
|
3826
3854
|
// drop_side_effect_free()
|
3827
3855
|
// remove side-effect-free parts which only affects return value
|
3828
|
-
(function(def){
|
3856
|
+
(function(def) {
|
3829
3857
|
// Drop side-effect-free elements from an array of expressions.
|
3830
3858
|
// Returns an array of expressions with side-effects or null
|
3831
3859
|
// if all elements were dropped. Note: original array may be
|
@@ -3848,7 +3876,7 @@ merge(Compressor.prototype, {
|
|
3848
3876
|
def(AST_Node, return_this);
|
3849
3877
|
def(AST_Constant, return_null);
|
3850
3878
|
def(AST_This, return_null);
|
3851
|
-
def(AST_Call, function(compressor, first_in_statement){
|
3879
|
+
def(AST_Call, function(compressor, first_in_statement) {
|
3852
3880
|
if (!this.is_expr_pure(compressor)) {
|
3853
3881
|
if (this.expression.is_call_pure(compressor)) {
|
3854
3882
|
var exprs = this.args.slice();
|
@@ -3874,7 +3902,7 @@ merge(Compressor.prototype, {
|
|
3874
3902
|
def(AST_Function, return_null);
|
3875
3903
|
def(AST_Arrow, return_null);
|
3876
3904
|
def(AST_ClassExpression, return_null);
|
3877
|
-
def(AST_Binary, function(compressor, first_in_statement){
|
3905
|
+
def(AST_Binary, function(compressor, first_in_statement) {
|
3878
3906
|
var right = this.right.drop_side_effect_free(compressor);
|
3879
3907
|
if (!right) return this.left.drop_side_effect_free(compressor, first_in_statement);
|
3880
3908
|
if (lazy_op(this.operator)) {
|
@@ -3888,7 +3916,7 @@ merge(Compressor.prototype, {
|
|
3888
3916
|
return make_sequence(this, [ left, right ]);
|
3889
3917
|
}
|
3890
3918
|
});
|
3891
|
-
def(AST_Assign, function(compressor){
|
3919
|
+
def(AST_Assign, function(compressor) {
|
3892
3920
|
var left = this.left;
|
3893
3921
|
if (left.has_side_effects(compressor)
|
3894
3922
|
|| compressor.has_directive("use strict")
|
@@ -3905,7 +3933,7 @@ merge(Compressor.prototype, {
|
|
3905
3933
|
}
|
3906
3934
|
return this;
|
3907
3935
|
});
|
3908
|
-
def(AST_Conditional, function(compressor){
|
3936
|
+
def(AST_Conditional, function(compressor) {
|
3909
3937
|
var consequent = this.consequent.drop_side_effect_free(compressor);
|
3910
3938
|
var alternative = this.alternative.drop_side_effect_free(compressor);
|
3911
3939
|
if (consequent === this.consequent && alternative === this.alternative) return this;
|
@@ -3924,7 +3952,7 @@ merge(Compressor.prototype, {
|
|
3924
3952
|
node.alternative = alternative;
|
3925
3953
|
return node;
|
3926
3954
|
});
|
3927
|
-
def(AST_Unary, function(compressor, first_in_statement){
|
3955
|
+
def(AST_Unary, function(compressor, first_in_statement) {
|
3928
3956
|
if (unary_side_effects(this.operator)) {
|
3929
3957
|
this.write_only = !this.expression.has_side_effects(compressor);
|
3930
3958
|
return this;
|
@@ -3940,22 +3968,22 @@ merge(Compressor.prototype, {
|
|
3940
3968
|
def(AST_SymbolRef, function(compressor) {
|
3941
3969
|
return this.is_declared(compressor) ? null : this;
|
3942
3970
|
});
|
3943
|
-
def(AST_Object, function(compressor, first_in_statement){
|
3971
|
+
def(AST_Object, function(compressor, first_in_statement) {
|
3944
3972
|
var values = trim(this.properties, compressor, first_in_statement);
|
3945
3973
|
return values && make_sequence(this, values);
|
3946
3974
|
});
|
3947
|
-
def(AST_ObjectProperty, function(compressor, first_in_statement){
|
3975
|
+
def(AST_ObjectProperty, function(compressor, first_in_statement) {
|
3948
3976
|
return this.value.drop_side_effect_free(compressor, first_in_statement);
|
3949
3977
|
});
|
3950
|
-
def(AST_Array, function(compressor, first_in_statement){
|
3978
|
+
def(AST_Array, function(compressor, first_in_statement) {
|
3951
3979
|
var values = trim(this.elements, compressor, first_in_statement);
|
3952
3980
|
return values && make_sequence(this, values);
|
3953
3981
|
});
|
3954
|
-
def(AST_Dot, function(compressor, first_in_statement){
|
3982
|
+
def(AST_Dot, function(compressor, first_in_statement) {
|
3955
3983
|
if (this.expression.may_throw_on_access(compressor)) return this;
|
3956
3984
|
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
3957
3985
|
});
|
3958
|
-
def(AST_Sub, function(compressor, first_in_statement){
|
3986
|
+
def(AST_Sub, function(compressor, first_in_statement) {
|
3959
3987
|
if (this.expression.may_throw_on_access(compressor)) return this;
|
3960
3988
|
var expression = this.expression.drop_side_effect_free(compressor, first_in_statement);
|
3961
3989
|
if (!expression) return this.property.drop_side_effect_free(compressor, first_in_statement);
|
@@ -3963,7 +3991,7 @@ merge(Compressor.prototype, {
|
|
3963
3991
|
if (!property) return expression;
|
3964
3992
|
return make_sequence(this, [ expression, property ]);
|
3965
3993
|
});
|
3966
|
-
def(AST_Sequence, function(compressor){
|
3994
|
+
def(AST_Sequence, function(compressor) {
|
3967
3995
|
var last = this.tail_node();
|
3968
3996
|
var expr = last.drop_side_effect_free(compressor);
|
3969
3997
|
if (expr === last) return this;
|
@@ -3971,19 +3999,19 @@ merge(Compressor.prototype, {
|
|
3971
3999
|
if (expr) expressions.push(expr);
|
3972
4000
|
return make_sequence(this, expressions);
|
3973
4001
|
});
|
3974
|
-
def(AST_Expansion, function(compressor, first_in_statement){
|
4002
|
+
def(AST_Expansion, function(compressor, first_in_statement) {
|
3975
4003
|
return this.expression.drop_side_effect_free(compressor, first_in_statement);
|
3976
4004
|
});
|
3977
4005
|
def(AST_TemplateSegment, return_null);
|
3978
|
-
def(AST_TemplateString, function(compressor){
|
4006
|
+
def(AST_TemplateString, function(compressor) {
|
3979
4007
|
var values = trim(this.segments, compressor, first_in_statement);
|
3980
4008
|
return values && make_sequence(this, values);
|
3981
4009
|
});
|
3982
|
-
})(function(node, func){
|
4010
|
+
})(function(node, func) {
|
3983
4011
|
node.DEFMETHOD("drop_side_effect_free", func);
|
3984
4012
|
});
|
3985
4013
|
|
3986
|
-
OPT(AST_SimpleStatement, function(self, compressor){
|
4014
|
+
OPT(AST_SimpleStatement, function(self, compressor) {
|
3987
4015
|
if (compressor.option("side_effects")) {
|
3988
4016
|
var body = self.body;
|
3989
4017
|
var node = body.drop_side_effect_free(compressor, true);
|
@@ -3998,7 +4026,7 @@ merge(Compressor.prototype, {
|
|
3998
4026
|
return self;
|
3999
4027
|
});
|
4000
4028
|
|
4001
|
-
OPT(AST_While, function(self, compressor){
|
4029
|
+
OPT(AST_While, function(self, compressor) {
|
4002
4030
|
return compressor.option("loops") ? make_node(AST_For, self, self).optimize(compressor) : self;
|
4003
4031
|
});
|
4004
4032
|
|
@@ -4016,7 +4044,7 @@ merge(Compressor.prototype, {
|
|
4016
4044
|
return found;
|
4017
4045
|
}
|
4018
4046
|
|
4019
|
-
OPT(AST_Do, function(self, compressor){
|
4047
|
+
OPT(AST_Do, function(self, compressor) {
|
4020
4048
|
if (!compressor.option("loops")) return self;
|
4021
4049
|
var cond = self.condition.tail_node().evaluate(compressor);
|
4022
4050
|
if (!(cond instanceof AST_Node)) {
|
@@ -4112,7 +4140,7 @@ merge(Compressor.prototype, {
|
|
4112
4140
|
}
|
4113
4141
|
}
|
4114
4142
|
|
4115
|
-
OPT(AST_For, function(self, compressor){
|
4143
|
+
OPT(AST_For, function(self, compressor) {
|
4116
4144
|
if (!compressor.option("loops")) return self;
|
4117
4145
|
if (compressor.option("side_effects") && self.init) {
|
4118
4146
|
self.init = self.init.drop_side_effect_free(compressor);
|
@@ -4149,7 +4177,7 @@ merge(Compressor.prototype, {
|
|
4149
4177
|
return if_break_in_loop(self, compressor);
|
4150
4178
|
});
|
4151
4179
|
|
4152
|
-
OPT(AST_If, function(self, compressor){
|
4180
|
+
OPT(AST_If, function(self, compressor) {
|
4153
4181
|
if (is_empty(self.alternative)) self.alternative = null;
|
4154
4182
|
|
4155
4183
|
if (!compressor.option("conditionals")) return self;
|
@@ -4293,7 +4321,7 @@ merge(Compressor.prototype, {
|
|
4293
4321
|
return self;
|
4294
4322
|
});
|
4295
4323
|
|
4296
|
-
OPT(AST_Switch, function(self, compressor){
|
4324
|
+
OPT(AST_Switch, function(self, compressor) {
|
4297
4325
|
if (!compressor.option("switches")) return self;
|
4298
4326
|
var branch;
|
4299
4327
|
var value = self.expression.evaluate(compressor);
|
@@ -4399,7 +4427,7 @@ merge(Compressor.prototype, {
|
|
4399
4427
|
}
|
4400
4428
|
});
|
4401
4429
|
|
4402
|
-
OPT(AST_Try, function(self, compressor){
|
4430
|
+
OPT(AST_Try, function(self, compressor) {
|
4403
4431
|
tighten_body(self.body, compressor);
|
4404
4432
|
if (self.bcatch && self.bfinally && all(self.bfinally.body, is_empty)) self.bfinally = null;
|
4405
4433
|
if (compressor.option("dead_code") && all(self.body, is_empty)) {
|
@@ -4424,7 +4452,7 @@ merge(Compressor.prototype, {
|
|
4424
4452
|
return self;
|
4425
4453
|
});
|
4426
4454
|
|
4427
|
-
AST_Definitions.DEFMETHOD("remove_initializers", function(){
|
4455
|
+
AST_Definitions.DEFMETHOD("remove_initializers", function() {
|
4428
4456
|
var decls = [];
|
4429
4457
|
this.definitions.forEach(function(def) {
|
4430
4458
|
if (def.name instanceof AST_SymbolDeclaration) {
|
@@ -4442,9 +4470,9 @@ merge(Compressor.prototype, {
|
|
4442
4470
|
this.definitions = decls;
|
4443
4471
|
});
|
4444
4472
|
|
4445
|
-
AST_Definitions.DEFMETHOD("to_assignments", function(compressor){
|
4473
|
+
AST_Definitions.DEFMETHOD("to_assignments", function(compressor) {
|
4446
4474
|
var reduce_vars = compressor.option("reduce_vars");
|
4447
|
-
var assignments = this.definitions.reduce(function(a, def){
|
4475
|
+
var assignments = this.definitions.reduce(function(a, def) {
|
4448
4476
|
if (def.value && !(def.name instanceof AST_Destructuring)) {
|
4449
4477
|
var name = make_node(AST_SymbolRef, def.name, def.name);
|
4450
4478
|
a.push(make_node(AST_Assign, def, {
|
@@ -4473,7 +4501,7 @@ merge(Compressor.prototype, {
|
|
4473
4501
|
return make_sequence(this, assignments);
|
4474
4502
|
});
|
4475
4503
|
|
4476
|
-
OPT(AST_Definitions, function(self, compressor){
|
4504
|
+
OPT(AST_Definitions, function(self, compressor) {
|
4477
4505
|
if (self.definitions.length == 0)
|
4478
4506
|
return make_node(AST_EmptyStatement, self);
|
4479
4507
|
return self;
|
@@ -4483,7 +4511,7 @@ merge(Compressor.prototype, {
|
|
4483
4511
|
return self;
|
4484
4512
|
});
|
4485
4513
|
|
4486
|
-
OPT(AST_Call, function(self, compressor){
|
4514
|
+
OPT(AST_Call, function(self, compressor) {
|
4487
4515
|
var exp = self.expression;
|
4488
4516
|
var fn = exp;
|
4489
4517
|
var simple_args = all(self.args, function(arg) {
|
@@ -4658,7 +4686,7 @@ merge(Compressor.prototype, {
|
|
4658
4686
|
} else {
|
4659
4687
|
first = make_node(AST_String, self, { value: "" });
|
4660
4688
|
}
|
4661
|
-
return elements.reduce(function(prev, el){
|
4689
|
+
return elements.reduce(function(prev, el) {
|
4662
4690
|
return make_node(AST_Binary, el, {
|
4663
4691
|
operator : "+",
|
4664
4692
|
left : prev,
|
@@ -4923,7 +4951,8 @@ merge(Compressor.prototype, {
|
|
4923
4951
|
if (!safe_to_inject) return false;
|
4924
4952
|
for (var j = stat.definitions.length; --j >= 0;) {
|
4925
4953
|
var name = stat.definitions[j].name;
|
4926
|
-
if (
|
4954
|
+
if (name instanceof AST_Destructuring
|
4955
|
+
|| block_scoped[name.name]
|
4927
4956
|
|| identifier_atom(name.name)
|
4928
4957
|
|| scope.var_names()[name.name]) {
|
4929
4958
|
return false;
|
@@ -5044,7 +5073,7 @@ merge(Compressor.prototype, {
|
|
5044
5073
|
}
|
5045
5074
|
});
|
5046
5075
|
|
5047
|
-
OPT(AST_New, function(self, compressor){
|
5076
|
+
OPT(AST_New, function(self, compressor) {
|
5048
5077
|
if (compressor.option("unsafe")) {
|
5049
5078
|
var exp = self.expression;
|
5050
5079
|
if (is_undeclared_ref(exp)) {
|
@@ -5061,7 +5090,7 @@ merge(Compressor.prototype, {
|
|
5061
5090
|
return self;
|
5062
5091
|
});
|
5063
5092
|
|
5064
|
-
OPT(AST_Sequence, function(self, compressor){
|
5093
|
+
OPT(AST_Sequence, function(self, compressor) {
|
5065
5094
|
if (!compressor.option("side_effects")) return self;
|
5066
5095
|
var expressions = [];
|
5067
5096
|
filter_for_side_effects();
|
@@ -5099,7 +5128,7 @@ merge(Compressor.prototype, {
|
|
5099
5128
|
}
|
5100
5129
|
});
|
5101
5130
|
|
5102
|
-
AST_Unary.DEFMETHOD("lift_sequences", function(compressor){
|
5131
|
+
AST_Unary.DEFMETHOD("lift_sequences", function(compressor) {
|
5103
5132
|
if (compressor.option("sequences")) {
|
5104
5133
|
if (this.expression instanceof AST_Sequence) {
|
5105
5134
|
var x = this.expression.expressions.slice();
|
@@ -5112,11 +5141,11 @@ merge(Compressor.prototype, {
|
|
5112
5141
|
return this;
|
5113
5142
|
});
|
5114
5143
|
|
5115
|
-
OPT(AST_UnaryPostfix, function(self, compressor){
|
5144
|
+
OPT(AST_UnaryPostfix, function(self, compressor) {
|
5116
5145
|
return self.lift_sequences(compressor);
|
5117
5146
|
});
|
5118
5147
|
|
5119
|
-
OPT(AST_UnaryPrefix, function(self, compressor){
|
5148
|
+
OPT(AST_UnaryPrefix, function(self, compressor) {
|
5120
5149
|
var e = self.expression;
|
5121
5150
|
if (self.operator == "delete"
|
5122
5151
|
&& !(e instanceof AST_SymbolRef
|
@@ -5190,7 +5219,7 @@ merge(Compressor.prototype, {
|
|
5190
5219
|
return self;
|
5191
5220
|
});
|
5192
5221
|
|
5193
|
-
AST_Binary.DEFMETHOD("lift_sequences", function(compressor){
|
5222
|
+
AST_Binary.DEFMETHOD("lift_sequences", function(compressor) {
|
5194
5223
|
if (compressor.option("sequences")) {
|
5195
5224
|
if (this.left instanceof AST_Sequence) {
|
5196
5225
|
var x = this.left.expressions.slice();
|
@@ -5232,7 +5261,7 @@ merge(Compressor.prototype, {
|
|
5232
5261
|
|| node instanceof AST_Class;
|
5233
5262
|
}
|
5234
5263
|
|
5235
|
-
OPT(AST_Binary, function(self, compressor){
|
5264
|
+
OPT(AST_Binary, function(self, compressor) {
|
5236
5265
|
function reversible() {
|
5237
5266
|
return self.left.is_constant()
|
5238
5267
|
|| self.right.is_constant()
|
@@ -5662,7 +5691,7 @@ merge(Compressor.prototype, {
|
|
5662
5691
|
return self;
|
5663
5692
|
});
|
5664
5693
|
|
5665
|
-
OPT(AST_SymbolExport, function(self, compressor){
|
5694
|
+
OPT(AST_SymbolExport, function(self, compressor) {
|
5666
5695
|
return self;
|
5667
5696
|
});
|
5668
5697
|
|
@@ -5677,7 +5706,7 @@ merge(Compressor.prototype, {
|
|
5677
5706
|
return node;
|
5678
5707
|
}
|
5679
5708
|
|
5680
|
-
OPT(AST_SymbolRef, function(self, compressor){
|
5709
|
+
OPT(AST_SymbolRef, function(self, compressor) {
|
5681
5710
|
var def = self.resolve_defines(compressor);
|
5682
5711
|
if (def) {
|
5683
5712
|
return def.optimize(compressor);
|
@@ -5813,7 +5842,7 @@ merge(Compressor.prototype, {
|
|
5813
5842
|
return lhs instanceof AST_SymbolRef || lhs.TYPE === self.TYPE;
|
5814
5843
|
}
|
5815
5844
|
|
5816
|
-
OPT(AST_Undefined, function(self, compressor){
|
5845
|
+
OPT(AST_Undefined, function(self, compressor) {
|
5817
5846
|
if (compressor.option("unsafe_undefined")) {
|
5818
5847
|
var undef = find_variable(compressor, "undefined");
|
5819
5848
|
if (undef) {
|
@@ -5836,7 +5865,7 @@ merge(Compressor.prototype, {
|
|
5836
5865
|
});
|
5837
5866
|
});
|
5838
5867
|
|
5839
|
-
OPT(AST_Infinity, function(self, compressor){
|
5868
|
+
OPT(AST_Infinity, function(self, compressor) {
|
5840
5869
|
var lhs = is_lhs(compressor.self(), compressor.parent());
|
5841
5870
|
if (lhs && is_atomic(lhs, self)) return self;
|
5842
5871
|
if (compressor.option("keep_infinity")
|
@@ -5854,7 +5883,7 @@ merge(Compressor.prototype, {
|
|
5854
5883
|
});
|
5855
5884
|
});
|
5856
5885
|
|
5857
|
-
OPT(AST_NaN, function(self, compressor){
|
5886
|
+
OPT(AST_NaN, function(self, compressor) {
|
5858
5887
|
var lhs = is_lhs(compressor.self(), compressor.parent());
|
5859
5888
|
if (lhs && !is_atomic(lhs, self)
|
5860
5889
|
|| find_variable(compressor, "NaN")) {
|
@@ -5892,9 +5921,9 @@ merge(Compressor.prototype, {
|
|
5892
5921
|
return reachable;
|
5893
5922
|
}
|
5894
5923
|
|
5895
|
-
var ASSIGN_OPS = [
|
5896
|
-
var ASSIGN_OPS_COMMUTATIVE = [
|
5897
|
-
OPT(AST_Assign, function(self, compressor){
|
5924
|
+
var ASSIGN_OPS = [ "+", "-", "/", "*", "%", ">>", "<<", ">>>", "|", "^", "&" ];
|
5925
|
+
var ASSIGN_OPS_COMMUTATIVE = [ "*", "|", "^", "&" ];
|
5926
|
+
OPT(AST_Assign, function(self, compressor) {
|
5898
5927
|
var def;
|
5899
5928
|
if (compressor.option("dead_code")
|
5900
5929
|
&& self.left instanceof AST_SymbolRef
|
@@ -5954,7 +5983,7 @@ merge(Compressor.prototype, {
|
|
5954
5983
|
}
|
5955
5984
|
});
|
5956
5985
|
|
5957
|
-
OPT(AST_DefaultAssign, function(self, compressor){
|
5986
|
+
OPT(AST_DefaultAssign, function(self, compressor) {
|
5958
5987
|
if (!compressor.option("evaluate")) {
|
5959
5988
|
return self;
|
5960
5989
|
}
|
@@ -5971,7 +6000,7 @@ merge(Compressor.prototype, {
|
|
5971
6000
|
return self;
|
5972
6001
|
});
|
5973
6002
|
|
5974
|
-
OPT(AST_Conditional, function(self, compressor){
|
6003
|
+
OPT(AST_Conditional, function(self, compressor) {
|
5975
6004
|
if (!compressor.option("conditionals")) return self;
|
5976
6005
|
// This looks like lift_sequences(), should probably be under "sequences"
|
5977
6006
|
if (self.condition instanceof AST_Sequence) {
|
@@ -6177,7 +6206,7 @@ merge(Compressor.prototype, {
|
|
6177
6206
|
}
|
6178
6207
|
});
|
6179
6208
|
|
6180
|
-
OPT(AST_Boolean, function(self, compressor){
|
6209
|
+
OPT(AST_Boolean, function(self, compressor) {
|
6181
6210
|
if (compressor.in_boolean_context()) return make_node(AST_Number, self, {
|
6182
6211
|
value: +self.value
|
6183
6212
|
});
|
@@ -6206,7 +6235,17 @@ merge(Compressor.prototype, {
|
|
6206
6235
|
return self;
|
6207
6236
|
});
|
6208
6237
|
|
6209
|
-
|
6238
|
+
function safe_to_flatten(value, compressor) {
|
6239
|
+
if (value instanceof AST_SymbolRef) {
|
6240
|
+
value = value.fixed_value();
|
6241
|
+
}
|
6242
|
+
if (!value) return false;
|
6243
|
+
return !(value instanceof AST_Lambda || value instanceof AST_Class)
|
6244
|
+
|| compressor.parent() instanceof AST_New
|
6245
|
+
|| !value.contains_this();
|
6246
|
+
}
|
6247
|
+
|
6248
|
+
OPT(AST_Sub, function(self, compressor) {
|
6210
6249
|
var expr = self.expression;
|
6211
6250
|
var prop = self.property;
|
6212
6251
|
if (compressor.option("properties")) {
|
@@ -6233,6 +6272,51 @@ merge(Compressor.prototype, {
|
|
6233
6272
|
}
|
6234
6273
|
}
|
6235
6274
|
}
|
6275
|
+
var fn;
|
6276
|
+
OPT_ARGUMENTS: if (compressor.option("arguments")
|
6277
|
+
&& expr instanceof AST_SymbolRef
|
6278
|
+
&& expr.name == "arguments"
|
6279
|
+
&& expr.definition().orig.length == 1
|
6280
|
+
&& (fn = expr.scope) instanceof AST_Lambda
|
6281
|
+
&& fn.uses_arguments
|
6282
|
+
&& !(fn instanceof AST_Arrow)
|
6283
|
+
&& prop instanceof AST_Number) {
|
6284
|
+
var index = prop.getValue();
|
6285
|
+
var params = Object.create(null);
|
6286
|
+
var argnames = fn.argnames;
|
6287
|
+
for (var n = 0; n < argnames.length; n++) {
|
6288
|
+
if (!(argnames[n] instanceof AST_SymbolFunarg)) {
|
6289
|
+
break OPT_ARGUMENTS; // destructuring parameter - bail
|
6290
|
+
}
|
6291
|
+
var param = argnames[n].name;
|
6292
|
+
if (param in params) {
|
6293
|
+
break OPT_ARGUMENTS; // duplicate parameter - bail
|
6294
|
+
}
|
6295
|
+
params[param] = true;
|
6296
|
+
}
|
6297
|
+
var argname = fn.argnames[index];
|
6298
|
+
if (argname && compressor.has_directive("use strict")) {
|
6299
|
+
var def = argname.definition();
|
6300
|
+
if (!compressor.option("reduce_vars") || def.assignments || def.orig.length > 1) {
|
6301
|
+
argname = null;
|
6302
|
+
}
|
6303
|
+
} else if (!argname && !compressor.option("keep_fargs") && index < fn.argnames.length + 5) {
|
6304
|
+
while (index >= fn.argnames.length) {
|
6305
|
+
argname = make_node(AST_SymbolFunarg, fn, {
|
6306
|
+
name: fn.make_var_name("argument_" + fn.argnames.length),
|
6307
|
+
scope: fn
|
6308
|
+
});
|
6309
|
+
fn.argnames.push(argname);
|
6310
|
+
fn.enclosed.push(fn.def_variable(argname));
|
6311
|
+
}
|
6312
|
+
}
|
6313
|
+
if (argname) {
|
6314
|
+
var sym = make_node(AST_SymbolRef, self, argname);
|
6315
|
+
sym.reference({});
|
6316
|
+
delete argname.__unused;
|
6317
|
+
return sym;
|
6318
|
+
}
|
6319
|
+
}
|
6236
6320
|
if (is_lhs(self, compressor.parent())) return self;
|
6237
6321
|
if (key !== prop) {
|
6238
6322
|
var sub = self.flatten_object(property, compressor);
|
@@ -6245,7 +6329,8 @@ merge(Compressor.prototype, {
|
|
6245
6329
|
&& prop instanceof AST_Number && expr instanceof AST_Array) {
|
6246
6330
|
var index = prop.getValue();
|
6247
6331
|
var elements = expr.elements;
|
6248
|
-
|
6332
|
+
var retValue = elements[index];
|
6333
|
+
FLATTEN: if (safe_to_flatten(retValue, compressor)) {
|
6249
6334
|
var flatten = true;
|
6250
6335
|
var values = [];
|
6251
6336
|
for (var i = elements.length; --i > index;) {
|
@@ -6255,7 +6340,6 @@ merge(Compressor.prototype, {
|
|
6255
6340
|
if (flatten && value.has_side_effects(compressor)) flatten = false;
|
6256
6341
|
}
|
6257
6342
|
}
|
6258
|
-
var retValue = elements[index];
|
6259
6343
|
if (retValue instanceof AST_Expansion) break FLATTEN;
|
6260
6344
|
retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
|
6261
6345
|
if (!flatten) values.unshift(retValue);
|
@@ -6279,32 +6363,6 @@ merge(Compressor.prototype, {
|
|
6279
6363
|
});
|
6280
6364
|
}
|
6281
6365
|
}
|
6282
|
-
var fn;
|
6283
|
-
if (compressor.option("arguments")
|
6284
|
-
&& expr instanceof AST_SymbolRef
|
6285
|
-
&& expr.name == "arguments"
|
6286
|
-
&& expr.definition().orig.length == 1
|
6287
|
-
&& (fn = expr.scope) instanceof AST_Lambda
|
6288
|
-
&& !(fn instanceof AST_Arrow)
|
6289
|
-
&& prop instanceof AST_Number) {
|
6290
|
-
var index = prop.getValue();
|
6291
|
-
var argname = fn.argnames[index];
|
6292
|
-
if (!argname && !compressor.option("keep_fargs")) {
|
6293
|
-
while (index >= fn.argnames.length) {
|
6294
|
-
argname = make_node(AST_SymbolFunarg, fn, {
|
6295
|
-
name: fn.make_var_name("argument_" + fn.argnames.length),
|
6296
|
-
scope: fn
|
6297
|
-
});
|
6298
|
-
fn.argnames.push(argname);
|
6299
|
-
fn.enclosed.push(fn.def_variable(argname));
|
6300
|
-
}
|
6301
|
-
}
|
6302
|
-
if (argname) {
|
6303
|
-
var sym = make_node(AST_SymbolRef, self, argname);
|
6304
|
-
sym.reference({});
|
6305
|
-
return sym;
|
6306
|
-
}
|
6307
|
-
}
|
6308
6366
|
var ev = self.evaluate(compressor);
|
6309
6367
|
if (ev !== self) {
|
6310
6368
|
ev = make_node_from_constant(ev, self).optimize(compressor);
|
@@ -6337,10 +6395,7 @@ merge(Compressor.prototype, {
|
|
6337
6395
|
return prop instanceof AST_ObjectKeyVal
|
6338
6396
|
|| arrows && prop instanceof AST_ConciseMethod && !prop.is_generator;
|
6339
6397
|
})) break;
|
6340
|
-
|
6341
|
-
if ((value instanceof AST_Accessor || value instanceof AST_Function)
|
6342
|
-
&& !(compressor.parent() instanceof AST_New)
|
6343
|
-
&& value.contains_this()) break;
|
6398
|
+
if (!safe_to_flatten(prop.value, compressor)) break;
|
6344
6399
|
return make_node(AST_Sub, this, {
|
6345
6400
|
expression: make_node(AST_Array, expr, {
|
6346
6401
|
elements: props.map(function(prop) {
|
@@ -6362,7 +6417,7 @@ merge(Compressor.prototype, {
|
|
6362
6417
|
}
|
6363
6418
|
});
|
6364
6419
|
|
6365
|
-
OPT(AST_Dot, function(self, compressor){
|
6420
|
+
OPT(AST_Dot, function(self, compressor) {
|
6366
6421
|
if (self.property == "arguments" || self.property == "caller") {
|
6367
6422
|
compressor.warn("Function.protoype.{prop} not supported [{file}:{line},{col}]", {
|
6368
6423
|
prop: self.property,
|
@@ -6432,19 +6487,19 @@ merge(Compressor.prototype, {
|
|
6432
6487
|
]).optimize(compressor));
|
6433
6488
|
}
|
6434
6489
|
return self;
|
6435
|
-
}
|
6490
|
+
}
|
6436
6491
|
OPT(AST_Array, literals_in_boolean_context);
|
6437
6492
|
OPT(AST_Object, literals_in_boolean_context);
|
6438
6493
|
OPT(AST_RegExp, literals_in_boolean_context);
|
6439
6494
|
|
6440
|
-
OPT(AST_Return, function(self, compressor){
|
6495
|
+
OPT(AST_Return, function(self, compressor) {
|
6441
6496
|
if (self.value && is_undefined(self.value, compressor)) {
|
6442
6497
|
self.value = null;
|
6443
6498
|
}
|
6444
6499
|
return self;
|
6445
6500
|
});
|
6446
6501
|
|
6447
|
-
OPT(AST_Arrow, function(self, compressor){
|
6502
|
+
OPT(AST_Arrow, function(self, compressor) {
|
6448
6503
|
if (!(self.body instanceof AST_Node)) {
|
6449
6504
|
self = opt_AST_Lambda(self, compressor);
|
6450
6505
|
}
|
@@ -6457,7 +6512,7 @@ merge(Compressor.prototype, {
|
|
6457
6512
|
return self;
|
6458
6513
|
});
|
6459
6514
|
|
6460
|
-
OPT(AST_Function, function(self, compressor){
|
6515
|
+
OPT(AST_Function, function(self, compressor) {
|
6461
6516
|
self = opt_AST_Lambda(self, compressor);
|
6462
6517
|
if (compressor.option("unsafe_arrows")
|
6463
6518
|
&& compressor.option("ecma") >= 6
|
@@ -6478,28 +6533,28 @@ merge(Compressor.prototype, {
|
|
6478
6533
|
return self;
|
6479
6534
|
});
|
6480
6535
|
|
6481
|
-
OPT(AST_Class, function(self, compressor){
|
6536
|
+
OPT(AST_Class, function(self, compressor) {
|
6482
6537
|
// HACK to avoid compress failure.
|
6483
6538
|
// AST_Class is not really an AST_Scope/AST_Block as it lacks a body.
|
6484
6539
|
return self;
|
6485
6540
|
});
|
6486
6541
|
|
6487
|
-
OPT(AST_Yield, function(self, compressor){
|
6542
|
+
OPT(AST_Yield, function(self, compressor) {
|
6488
6543
|
if (self.expression && !self.is_star && is_undefined(self.expression, compressor)) {
|
6489
6544
|
self.expression = null;
|
6490
6545
|
}
|
6491
6546
|
return self;
|
6492
6547
|
});
|
6493
6548
|
|
6494
|
-
OPT(AST_VarDef, function(self, compressor){
|
6549
|
+
OPT(AST_VarDef, function(self, compressor) {
|
6495
6550
|
var defines = compressor.option("global_defs");
|
6496
6551
|
if (defines && HOP(defines, self.name.name)) {
|
6497
|
-
compressor.warn(
|
6552
|
+
compressor.warn("global_defs " + self.name.name + " redefined [{file}:{line},{col}]", self.start);
|
6498
6553
|
}
|
6499
6554
|
return self;
|
6500
6555
|
});
|
6501
6556
|
|
6502
|
-
OPT(AST_TemplateString, function(self, compressor){
|
6557
|
+
OPT(AST_TemplateString, function(self, compressor) {
|
6503
6558
|
if (!compressor.option("evaluate")
|
6504
6559
|
|| compressor.parent() instanceof AST_PrefixedTemplateString)
|
6505
6560
|
return self;
|
@@ -6524,7 +6579,7 @@ merge(Compressor.prototype, {
|
|
6524
6579
|
return segments.length == 1 ? make_node(AST_String, self, segments[0]) : self;
|
6525
6580
|
});
|
6526
6581
|
|
6527
|
-
OPT(AST_PrefixedTemplateString, function(self, compressor){
|
6582
|
+
OPT(AST_PrefixedTemplateString, function(self, compressor) {
|
6528
6583
|
return self;
|
6529
6584
|
});
|
6530
6585
|
|
@@ -6551,7 +6606,7 @@ merge(Compressor.prototype, {
|
|
6551
6606
|
|
6552
6607
|
OPT(AST_ObjectProperty, lift_key);
|
6553
6608
|
|
6554
|
-
OPT(AST_ConciseMethod, function(self, compressor){
|
6609
|
+
OPT(AST_ConciseMethod, function(self, compressor) {
|
6555
6610
|
lift_key(self, compressor);
|
6556
6611
|
// p(){return x;} ---> p:()=>x
|
6557
6612
|
if (compressor.option("arrows")
|
@@ -6575,7 +6630,7 @@ merge(Compressor.prototype, {
|
|
6575
6630
|
return self;
|
6576
6631
|
});
|
6577
6632
|
|
6578
|
-
OPT(AST_ObjectKeyVal, function(self, compressor){
|
6633
|
+
OPT(AST_ObjectKeyVal, function(self, compressor) {
|
6579
6634
|
lift_key(self, compressor);
|
6580
6635
|
// p:function(){} ---> p(){}
|
6581
6636
|
// p:function*(){} ---> *p(){}
|