@@ -5096,6 +5096,38 @@ merge(Compressor.prototype, {
|
|||||||
return sym;
|
return sym;
|
||||||
};
|
};
|
||||||
var assign_in_use = Object.create(null);
|
var assign_in_use = Object.create(null);
|
||||||
|
var find_variable = function(name) {
|
||||||
|
find_variable = compose(self, 0, noop);
|
||||||
|
return find_variable(name);
|
||||||
|
|
||||||
|
function compose(child, level, find) {
|
||||||
|
var parent = compressor.parent(level);
|
||||||
|
if (!parent) return find;
|
||||||
|
if (parent instanceof AST_DestructuredKeyVal) {
|
||||||
|
var destructured = compressor.parent(level + 1);
|
||||||
|
if (parent.key === child) {
|
||||||
|
var fn = compressor.parent(level + 2);
|
||||||
|
if (fn instanceof AST_Lambda) {
|
||||||
|
return compose(fn, level + 3, fn.argnames.indexOf(destructured) >= 0 ? function(name) {
|
||||||
|
var def = find(name);
|
||||||
|
if (def) return def;
|
||||||
|
def = fn.variables.get(name);
|
||||||
|
if (def) {
|
||||||
|
var sym = def.orig[0];
|
||||||
|
if (sym instanceof AST_SymbolFunarg || sym instanceof AST_SymbolLambda) return def;
|
||||||
|
}
|
||||||
|
} : function(name) {
|
||||||
|
return find(name) || fn.variables.get(name);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return compose(destructured, level + 2, find);
|
||||||
|
}
|
||||||
|
return compose(parent, level + 1, parent.variables ? function(name) {
|
||||||
|
return find(name) || parent.variables.get(name);
|
||||||
|
} : find);
|
||||||
|
}
|
||||||
|
};
|
||||||
var for_ins = Object.create(null);
|
var for_ins = Object.create(null);
|
||||||
var in_use = [];
|
var in_use = [];
|
||||||
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
var in_use_ids = Object.create(null); // avoid expensive linear scans of in_use
|
||||||
@@ -5761,33 +5793,6 @@ merge(Compressor.prototype, {
|
|||||||
if (init instanceof AST_SymbolRef) return init;
|
if (init instanceof AST_SymbolRef) return init;
|
||||||
}
|
}
|
||||||
|
|
||||||
function find_variable(name) {
|
|
||||||
var level = 0;
|
|
||||||
var scope = self;
|
|
||||||
while (true) {
|
|
||||||
var in_arg = false;
|
|
||||||
do {
|
|
||||||
var parent = compressor.parent(level++);
|
|
||||||
if (parent instanceof AST_DestructuredKeyVal && parent.key === scope) {
|
|
||||||
var fn = compressor.parent(level + 1);
|
|
||||||
if (fn instanceof AST_Lambda) {
|
|
||||||
in_arg = fn.argnames.indexOf(compressor.parent(level)) >= 0;
|
|
||||||
level += 2;
|
|
||||||
scope = fn;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!parent) return;
|
|
||||||
scope = parent;
|
|
||||||
} while (!(scope instanceof AST_BlockScope));
|
|
||||||
var def = scope.variables.get(name);
|
|
||||||
if (!def) continue;
|
|
||||||
if (!in_arg) return def;
|
|
||||||
var sym = def.orig[0];
|
|
||||||
if (sym instanceof AST_SymbolFunarg || sym instanceof AST_SymbolLambda) return def;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function scan_ref_scoped(node, descend, init) {
|
function scan_ref_scoped(node, descend, init) {
|
||||||
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
|
if (node instanceof AST_Assign && node.left instanceof AST_SymbolRef) {
|
||||||
var def = node.left.definition();
|
var def = node.left.definition();
|
||||||
|
|||||||
@@ -1255,3 +1255,28 @@ issue_4240: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: "PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
issue_4355: {
|
||||||
|
options = {
|
||||||
|
dead_code: true,
|
||||||
|
evaluate: true,
|
||||||
|
loops: true,
|
||||||
|
side_effects: true,
|
||||||
|
unused: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
while (function() {
|
||||||
|
var a;
|
||||||
|
for (a in console.log("PASS"))
|
||||||
|
var b = 0;
|
||||||
|
}())
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(function() {
|
||||||
|
console.log("PASS");
|
||||||
|
})();
|
||||||
|
var c;
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user