proper scope look-up & statement trimming

This commit is contained in:
alexlamsl 2017-04-18 14:02:06 +08:00
parent 5d9f1da3ab
commit 1baf3a8f10
2 changed files with 8 additions and 20 deletions

View File

@ -642,12 +642,10 @@ merge(Compressor.prototype, {
// and if it has exactly one reference then attempt to replace its reference
// in the statement with the var value and then erase the var definition.
var self = compressor.self();
var var_defs_removed = false;
var scope = compressor.find_parent(AST_Scope);
var toplevel = compressor.option("toplevel");
for (var stat_index = statements.length; --stat_index >= 0;) {
var stat = statements[stat_index];
if (stat instanceof AST_Definitions) continue;
// Process child blocks of statement if present.
[stat, stat.body, stat.alternative, stat.bcatch, stat.bfinally].forEach(function(node) {
@ -681,8 +679,8 @@ merge(Compressor.prototype, {
var_names_seen[var_name] = true;
// Only interested in cases with just one reference to the variable.
var def = self.find_variable && self.find_variable(var_name);
if (!def || !def.references || def.references.length !== 1
var def = var_decl.name.definition();
if (def.references.length !== 1
|| var_name == "arguments" || (!toplevel && def.global)) {
side_effects_encountered = true;
continue;
@ -712,7 +710,7 @@ merge(Compressor.prototype, {
var value_has_side_effects = var_decl.value.has_side_effects(compressor);
// Non-constant single use vars can only be replaced in same scope.
if (ref.scope !== self) {
if (ref.scope !== scope) {
side_effects_encountered |= value_has_side_effects;
continue;
}
@ -740,7 +738,7 @@ merge(Compressor.prototype, {
|| (parent instanceof AST_Conditional && node !== parent.condition)
|| (node instanceof AST_SymbolRef
&& value_has_side_effects
&& !are_references_in_scope(node.definition(), self))
&& !are_references_in_scope(node.definition(), scope))
|| (parent instanceof AST_Binary
&& (parent.operator == "&&" || parent.operator == "||")
&& node === parent.right)
@ -774,13 +772,6 @@ merge(Compressor.prototype, {
}
}
// Remove extraneous empty statments in block after removing var definitions.
// Leave at least one statement in `statements`.
if (var_defs_removed) for (var i = statements.length; --i >= 0;) {
if (statements.length > 1 && statements[i] instanceof AST_EmptyStatement)
statements.splice(i, 1);
}
return statements;
function is_lvalue(node, parent) {
@ -795,8 +786,8 @@ merge(Compressor.prototype, {
var_defs.splice(var_defs_index, 1);
if (var_defs.length === 0) {
statements[prev_stat_index] = make_node(AST_EmptyStatement, self);
var_defs_removed = true;
statements.splice(prev_stat_index, 1);
stat_index--;
}
// Further optimize statement after substitution.
stat.reset_opt_flags(compressor);

View File

@ -282,10 +282,7 @@ collapse_vars_if: {
return "x" != "Bar" + x / 4 ? g9 : g5;
}
function f3(x) {
if (x) {
return 1;
}
return 2;
return x ? 1 : 2;
}
}
}