enhance collapse_vars (#3572)
This commit is contained in:
@@ -1235,7 +1235,7 @@ merge(Compressor.prototype, {
|
|||||||
var lvalues = get_lvalues(candidate);
|
var lvalues = get_lvalues(candidate);
|
||||||
var lhs_local = is_lhs_local(lhs);
|
var lhs_local = is_lhs_local(lhs);
|
||||||
if (!side_effects) side_effects = value_has_side_effects(candidate);
|
if (!side_effects) side_effects = value_has_side_effects(candidate);
|
||||||
var replace_all = replace_all_symbols();
|
var replace_all = replace_all_symbols(candidate);
|
||||||
var may_throw = candidate.may_throw(compressor) ? in_try ? function(node) {
|
var may_throw = candidate.may_throw(compressor) ? in_try ? function(node) {
|
||||||
return node.has_side_effects(compressor);
|
return node.has_side_effects(compressor);
|
||||||
} : side_effects_external : return_false;
|
} : side_effects_external : return_false;
|
||||||
@@ -1312,6 +1312,7 @@ merge(Compressor.prototype, {
|
|||||||
|
|
||||||
function in_conditional(node, parent) {
|
function in_conditional(node, parent) {
|
||||||
if (parent instanceof AST_Binary) return lazy_op[parent.operator] && parent.left !== node;
|
if (parent instanceof AST_Binary) return lazy_op[parent.operator] && parent.left !== node;
|
||||||
|
if (parent instanceof AST_Case) return parent.expression !== node;
|
||||||
if (parent instanceof AST_Conditional) return parent.condition !== node;
|
if (parent instanceof AST_Conditional) return parent.condition !== node;
|
||||||
return parent instanceof AST_If && parent.condition !== node;
|
return parent instanceof AST_If && parent.condition !== node;
|
||||||
}
|
}
|
||||||
@@ -1477,19 +1478,43 @@ merge(Compressor.prototype, {
|
|||||||
if (parent instanceof AST_Call) return node;
|
if (parent instanceof AST_Call) return node;
|
||||||
if (parent instanceof AST_Case) return node;
|
if (parent instanceof AST_Case) return node;
|
||||||
if (parent instanceof AST_Conditional) return node;
|
if (parent instanceof AST_Conditional) return node;
|
||||||
if (parent instanceof AST_Definitions) return find_stop(parent, level + 1);
|
if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1);
|
||||||
if (parent instanceof AST_Exit) return node;
|
if (parent instanceof AST_Exit) return node;
|
||||||
if (parent instanceof AST_If) return node;
|
if (parent instanceof AST_If) return node;
|
||||||
if (parent instanceof AST_IterationStatement) return node;
|
if (parent instanceof AST_IterationStatement) return node;
|
||||||
if (parent instanceof AST_PropAccess) return node;
|
if (parent instanceof AST_PropAccess) return node;
|
||||||
if (parent instanceof AST_Sequence) return find_stop(parent, level + 1);
|
if (parent instanceof AST_Sequence) {
|
||||||
if (parent instanceof AST_SimpleStatement) return find_stop(parent, level + 1);
|
return (parent.tail_node() === node ? find_stop : find_stop_unused)(parent, level + 1);
|
||||||
|
}
|
||||||
|
if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1);
|
||||||
if (parent instanceof AST_Switch) return node;
|
if (parent instanceof AST_Switch) return node;
|
||||||
if (parent instanceof AST_Unary) return node;
|
if (parent instanceof AST_Unary) return node;
|
||||||
if (parent instanceof AST_VarDef) return node;
|
if (parent instanceof AST_VarDef) return node;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function find_stop_unused(node, level) {
|
||||||
|
var parent = scanner.parent(level);
|
||||||
|
if (is_last_node(node, parent)) return node;
|
||||||
|
if (in_conditional(node, parent)) return node;
|
||||||
|
if (parent instanceof AST_Assign) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Binary) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Call) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Case) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Conditional) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Definitions) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Exit) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_If) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_IterationStatement) return node;
|
||||||
|
if (parent instanceof AST_PropAccess) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Sequence) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_SimpleStatement) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Switch) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_Unary) return find_stop_unused(parent, level + 1);
|
||||||
|
if (parent instanceof AST_VarDef) return find_stop_unused(parent, level + 1);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
function mangleable_var(var_def) {
|
function mangleable_var(var_def) {
|
||||||
var value = var_def.value;
|
var value = var_def.value;
|
||||||
if (!(value instanceof AST_SymbolRef)) return;
|
if (!(value instanceof AST_SymbolRef)) return;
|
||||||
@@ -1656,7 +1681,8 @@ merge(Compressor.prototype, {
|
|||||||
return get_rvalue(expr).has_side_effects(compressor);
|
return get_rvalue(expr).has_side_effects(compressor);
|
||||||
}
|
}
|
||||||
|
|
||||||
function replace_all_symbols() {
|
function replace_all_symbols(expr) {
|
||||||
|
if (expr instanceof AST_Unary) return false;
|
||||||
if (side_effects) return false;
|
if (side_effects) return false;
|
||||||
if (value_def) return true;
|
if (value_def) return true;
|
||||||
if (lhs instanceof AST_SymbolRef) {
|
if (lhs instanceof AST_SymbolRef) {
|
||||||
|
|||||||
@@ -6387,3 +6387,51 @@ issue_3562: {
|
|||||||
}
|
}
|
||||||
expect_stdout: "PASS PASS"
|
expect_stdout: "PASS PASS"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dot_throw_assign_sequence: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
var b;
|
||||||
|
b[0] = (a = "PASS", 0);
|
||||||
|
a = 1 + a;
|
||||||
|
} catch (c) {
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a = "FAIL";
|
||||||
|
try {
|
||||||
|
var b;
|
||||||
|
b[0] = (a = "PASS", 0);
|
||||||
|
a = 1 + a;
|
||||||
|
} catch (c) {
|
||||||
|
}
|
||||||
|
console.log(a);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|
||||||
|
call_assign_order: {
|
||||||
|
options = {
|
||||||
|
collapse_vars: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
var a, b = 1, c = 0, log = console.log;
|
||||||
|
(function() {
|
||||||
|
a = b = "PASS";
|
||||||
|
})((b = "FAIL", c++));
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
var a, b = 1, c = 0, log = console.log;
|
||||||
|
(function() {
|
||||||
|
a = b = "PASS";
|
||||||
|
})((b = "FAIL", c++));
|
||||||
|
log(a, b);
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS PASS"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user