@@ -297,6 +297,8 @@ merge(Compressor.prototype, {
297
297
if (node instanceof AST_SymbolRef) d.references.push(node);
298
298
d.fixed = false;
299
299
});
300
+
var in_loop = null;
301
+
var loop_ids = Object.create(null);
300
302
var tw = new TreeWalker(function(node, descend) {
301
303
node._squeezed = false;
302
304
node._optimized = false;
@@ -307,7 +309,7 @@ merge(Compressor.prototype, {
307
309
var d = node.definition();
308
310
d.references.push(node);
309
311
if (d.fixed === undefined || !safe_to_read(d)
310
-
|| is_modified(node, 0, is_immutable(node.fixed_value()))) {
312
+
|| is_modified(node, 0, is_immutable(node))) {
311
313
d.fixed = false;
312
314
} else {
313
315
var parent = tw.parent();
@@ -329,6 +331,7 @@ merge(Compressor.prototype, {
329
331
d.fixed = function() {
330
332
return node.value;
331
333
};
334
+
loop_ids[d.id] = in_loop;
332
335
mark(d, false);
333
336
descend();
334
337
} else {
@@ -384,6 +387,7 @@ merge(Compressor.prototype, {
384
387
d.fixed = function() {
385
388
return iife.args[i] || make_node(AST_Undefined, iife);
386
389
};
390
+
loop_ids[d.id] = in_loop;
387
391
mark(d, true);
388
392
} else {
389
393
d.fixed = false;
@@ -431,10 +435,13 @@ merge(Compressor.prototype, {
431
435
return true;
432
436
}
433
437
if (node instanceof AST_DWLoop) {
438
+
var saved_loop = in_loop;
439
+
in_loop = node;
434
440
push();
435
441
node.condition.walk(tw);
436
442
node.body.walk(tw);
437
443
pop();
444
+
in_loop = saved_loop;
438
445
return true;
439
446
}
440
447
if (node instanceof AST_LabeledStatement) {
@@ -445,6 +452,8 @@ merge(Compressor.prototype, {
445
452
}
446
453
if (node instanceof AST_For) {
447
454
if (node.init) node.init.walk(tw);
455
+
var saved_loop = in_loop;
456
+
in_loop = node;
448
457
if (node.condition) {
449
458
push();
450
459
node.condition.walk(tw);
@@ -458,14 +467,18 @@ merge(Compressor.prototype, {
458
467
node.step.walk(tw);
459
468
pop();
460
469
}
470
+
in_loop = saved_loop;
461
471
return true;
462
472
}
463
473
if (node instanceof AST_ForIn) {
464
474
node.init.walk(suppressor);
465
475
node.object.walk(tw);
476
+
var saved_loop = in_loop;
477
+
in_loop = node;
466
478
push();
467
479
node.body.walk(tw);
468
480
pop();
481
+
in_loop = saved_loop;
469
482
return true;
470
483
}
471
484
if (node instanceof AST_Try) {
@@ -535,10 +548,23 @@ merge(Compressor.prototype, {
535
548
}
536
549
def.references = [];
537
550
def.should_replace = undefined;
538
-
}
539
-
540
-
function is_immutable(value) {
541
-
return value && value.is_constant() || value instanceof AST_Lambda;
551
+
def.single_use = undefined;
552
+
}
553
+
554
+
function is_immutable(node) {
555
+
var value = node.fixed_value();
556
+
if (!value) return false;
557
+
if (value.is_constant()) return true;
558
+
if (compressor.option("unused")) {
559
+
var d = node.definition();
560
+
if (d.single_use === undefined) {
561
+
d.single_use = loop_ids[d.id] === in_loop
562
+
&& d.scope === node.scope
563
+
&& value.is_constant_expression();
564
+
}
565
+
if (d.references.length == 1 && d.single_use) return true;
566
+
}
567
+
return value instanceof AST_Lambda;
542
568
}
543
569
544
570
function is_modified(node, level, immutable) {
@@ -2115,6 +2141,22 @@ merge(Compressor.prototype, {
2115
2141
}
2116
2142
def(AST_Node, return_false);
2117
2143
def(AST_Constant, return_true);
2144
+
def(AST_Function, function(){
2145
+
var self = this;
2146
+
var result = true;
2147
+
self.walk(new TreeWalker(function(node) {
2148
+
if (!result) return true;
2149
+
if (node instanceof AST_SymbolRef) {
2150
+
var def = node.definition();
2151
+
if (self.enclosed.indexOf(def) >= 0
2152
+
&& self.variables.get(def.name) !== def) {
2153
+
result = false;
2154
+
return true;
2155
+
}
2156
+
}
2157
+
}));
2158
+
return result;
2159
+
});
2118
2160
def(AST_Unary, function(){
2119
2161
return this.expression.is_constant_expression();
2120
2162
});
@@ -4078,12 +4120,13 @@ merge(Compressor.prototype, {
4078
4120
d.fixed = fixed = make_node(AST_Function, fixed, fixed);
4079
4121
}
4080
4122
if (compressor.option("unused")
4081
-
&& fixed instanceof AST_Function
4082
4123
&& d.references.length == 1
4083
-
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
4084
-
&& !d.scope.uses_eval
4085
-
&& compressor.find_parent(AST_Scope) === fixed.parent_scope) {
4086
-
return fixed.clone(true);
4124
+
&& (d.single_use || fixed instanceof AST_Function
4125
+
&& !(d.scope.uses_arguments && d.orig[0] instanceof AST_SymbolFunarg)
4126
+
&& !d.scope.uses_eval
4127
+
&& compressor.find_parent(AST_Scope) === fixed.parent_scope)) {
4128
+
var value = fixed.optimize(compressor);
4129
+
return value === fixed ? fixed.clone(true) : value;
4087
4130
}
4088
4131
if (compressor.option("evaluate") && fixed) {
4089
4132
if (d.should_replace === undefined) {
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4