@@ -1088,6 +1088,7 @@ merge(Compressor.prototype, {
|
|||||||
function get_lhs(expr) {
|
function get_lhs(expr) {
|
||||||
if (expr instanceof AST_VarDef) {
|
if (expr instanceof AST_VarDef) {
|
||||||
var def = expr.name.definition();
|
var def = expr.name.definition();
|
||||||
|
if (!member(expr.name, def.orig)) return;
|
||||||
var declared = def.orig.length - def.eliminated;
|
var declared = def.orig.length - def.eliminated;
|
||||||
var referenced = def.references.length - def.replaced;
|
var referenced = def.references.length - def.replaced;
|
||||||
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
|
if (declared > 1 && !(expr.name instanceof AST_SymbolFunarg)
|
||||||
@@ -2434,47 +2435,18 @@ merge(Compressor.prototype, {
|
|||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
var sym;
|
return scan_ref_scoped(node, descend);
|
||||||
if (scope === self
|
|
||||||
&& (sym = assign_as_unused(node)) instanceof AST_SymbolRef
|
|
||||||
&& self.variables.get(sym.name) === sym.definition()) {
|
|
||||||
if (node instanceof AST_Assign) node.right.walk(tw);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_SymbolRef) {
|
|
||||||
var node_def = node.definition();
|
|
||||||
if (!(node_def.id in in_use_ids)) {
|
|
||||||
in_use_ids[node_def.id] = true;
|
|
||||||
in_use.push(node_def);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
if (node instanceof AST_Scope) {
|
|
||||||
var save_scope = scope;
|
|
||||||
scope = node;
|
|
||||||
descend();
|
|
||||||
scope = save_scope;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
self.walk(tw);
|
self.walk(tw);
|
||||||
// pass 2: for every used symbol we need to walk its
|
// pass 2: for every used symbol we need to walk its
|
||||||
// initialization code to figure out if it uses other
|
// initialization code to figure out if it uses other
|
||||||
// symbols (that may not be in_use).
|
// symbols (that may not be in_use).
|
||||||
|
tw = new TreeWalker(scan_ref_scoped);
|
||||||
for (var i = 0; i < in_use.length; ++i) {
|
for (var i = 0; i < in_use.length; ++i) {
|
||||||
in_use[i].orig.forEach(function(decl){
|
in_use[i].orig.forEach(function(decl){
|
||||||
// undeclared globals will be instanceof AST_SymbolRef
|
// undeclared globals will be instanceof AST_SymbolRef
|
||||||
var init = initializations.get(decl.name);
|
var init = initializations.get(decl.name);
|
||||||
if (init) init.forEach(function(init){
|
if (init) init.forEach(function(init){
|
||||||
var tw = new TreeWalker(function(node){
|
|
||||||
if (node instanceof AST_SymbolRef) {
|
|
||||||
var node_def = node.definition();
|
|
||||||
if (!(node_def.id in in_use_ids)) {
|
|
||||||
in_use_ids[node_def.id] = true;
|
|
||||||
in_use.push(node_def);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
init.walk(tw);
|
init.walk(tw);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@@ -2663,6 +2635,31 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
self.transform(tt);
|
self.transform(tt);
|
||||||
|
|
||||||
|
function scan_ref_scoped(node, descend) {
|
||||||
|
var sym;
|
||||||
|
if (scope === self
|
||||||
|
&& (sym = assign_as_unused(node)) instanceof AST_SymbolRef
|
||||||
|
&& self.variables.get(sym.name) === sym.definition()) {
|
||||||
|
if (node instanceof AST_Assign) node.right.walk(tw);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_SymbolRef) {
|
||||||
|
var node_def = node.definition();
|
||||||
|
if (!(node_def.id in in_use_ids)) {
|
||||||
|
in_use_ids[node_def.id] = true;
|
||||||
|
in_use.push(node_def);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (node instanceof AST_Scope) {
|
||||||
|
var save_scope = scope;
|
||||||
|
scope = node;
|
||||||
|
descend();
|
||||||
|
scope = save_scope;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
|
AST_Scope.DEFMETHOD("hoist_declarations", function(compressor){
|
||||||
|
|||||||
@@ -705,7 +705,7 @@ collapse_vars_lvalues_drop_assign: {
|
|||||||
function f2(x) { var z = x, a = ++z; return z += a; }
|
function f2(x) { var z = x, a = ++z; return z += a; }
|
||||||
function f3(x) { var a = (x -= 3); return x + a; }
|
function f3(x) { var a = (x -= 3); return x + a; }
|
||||||
function f4(x) { var a = (x -= 3); return x + a; }
|
function f4(x) { var a = (x -= 3); return x + a; }
|
||||||
function f5(x) { e1(); var v = e2(), c = v = --x; return x - c; }
|
function f5(x) { e1(), e2(); var c = --x; return x - c; }
|
||||||
function f6(x) { e1(), e2(); return --x - x; }
|
function f6(x) { e1(), e2(); return --x - x; }
|
||||||
function f7(x) { e1(); return x - (e2() - x); }
|
function f7(x) { e1(); return x - (e2() - x); }
|
||||||
function f8(x) { e1(); return x - (e2() - x); }
|
function f8(x) { e1(); return x - (e2() - x); }
|
||||||
@@ -2386,6 +2386,7 @@ duplicate_argname: {
|
|||||||
issue_2298: {
|
issue_2298: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
reduce_funcs: true,
|
reduce_funcs: true,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
@@ -3087,13 +3088,14 @@ issue_2437: {
|
|||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
!function() {
|
!function() {
|
||||||
if (xhrDesc)
|
if (xhrDesc) {
|
||||||
return result = !!(req = new XMLHttpRequest()).onreadystatechange,
|
var result = !!(req = new XMLHttpRequest()).onreadystatechange;
|
||||||
Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
|
return Object.defineProperty(XMLHttpRequest.prototype, "onreadystatechange", xhrDesc || {}),
|
||||||
result;
|
result;
|
||||||
|
}
|
||||||
var req = new XMLHttpRequest(), detectFunc = function() {};
|
var req = new XMLHttpRequest(), detectFunc = function() {};
|
||||||
req.onreadystatechange = detectFunc;
|
req.onreadystatechange = detectFunc,
|
||||||
var result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc;
|
result = req[SYMBOL_FAKE_ONREADYSTATECHANGE_1] === detectFunc,
|
||||||
req.onreadystatechange = null;
|
req.onreadystatechange = null;
|
||||||
}();
|
}();
|
||||||
}
|
}
|
||||||
@@ -3522,6 +3524,7 @@ issue_2436_12: {
|
|||||||
issue_2436_13: {
|
issue_2436_13: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
@@ -3622,6 +3625,7 @@ issue_2497: {
|
|||||||
issue_2506: {
|
issue_2506: {
|
||||||
options = {
|
options = {
|
||||||
collapse_vars: true,
|
collapse_vars: true,
|
||||||
|
passes: 2,
|
||||||
reduce_vars: true,
|
reduce_vars: true,
|
||||||
unused: true,
|
unused: true,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1299,3 +1299,83 @@ issue_2288: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_2516_1: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
function qux(x) {
|
||||||
|
bar.call(null, x);
|
||||||
|
}
|
||||||
|
function bar(x) {
|
||||||
|
var FOUR = 4;
|
||||||
|
var trouble = x || never_called();
|
||||||
|
var value = (FOUR - 1) * trouble;
|
||||||
|
console.log(value == 6 ? "PASS" : value);
|
||||||
|
}
|
||||||
|
Baz = qux;
|
||||||
|
}
|
||||||
|
var Baz;
|
||||||
|
foo();
|
||||||
|
Baz(2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {
|
||||||
|
Baz = function(x) {
|
||||||
|
(function(x) {
|
||||||
|
var trouble = x || never_called();
|
||||||
|
var value = (4 - 1) * trouble;
|
||||||
|
console.log(6 == value ? "PASS" : value);
|
||||||
|
}).call(null, x);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var Baz;
|
||||||
|
foo();
|
||||||
|
Baz(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
issue_2516_2: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
reduce_funcs: true,
|
||||||
|
reduce_vars: true,
|
||||||
|
passes: 2,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
function foo() {
|
||||||
|
function qux(x) {
|
||||||
|
bar.call(null, x);
|
||||||
|
}
|
||||||
|
function bar(x) {
|
||||||
|
var FOUR = 4;
|
||||||
|
var trouble = x || never_called();
|
||||||
|
var value = (FOUR - 1) * trouble;
|
||||||
|
console.log(value == 6 ? "PASS" : value);
|
||||||
|
}
|
||||||
|
Baz = qux;
|
||||||
|
}
|
||||||
|
var Baz;
|
||||||
|
foo();
|
||||||
|
Baz(2);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
function foo() {
|
||||||
|
Baz = function(x) {
|
||||||
|
(function(x) {
|
||||||
|
var value = (4 - 1) * (x || never_called());
|
||||||
|
console.log(6 == value ? "PASS" : value);
|
||||||
|
}).call(null, x);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
var Baz;
|
||||||
|
foo();
|
||||||
|
Baz(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user