fix corner case in conditionals (#3329)

fixes #3245
fixes #3257
fixes #3260
fixes #3269
fixes #3271
fixes #3278
fixes #3309
fixes #3319
fixes #3321
This commit is contained in:
Alex Lam S.L
2019-03-13 04:28:21 +08:00
committed by GitHub
parent b1c0664066
commit 008c236137
2 changed files with 49 additions and 3 deletions

View File

@@ -6051,12 +6051,14 @@ merge(Compressor.prototype, {
if (seq_tail instanceof AST_Assign) {
var is_eq = seq_tail.operator == "=";
var alt_tail = is_eq ? alternative.tail_node() : alternative;
if ((is_eq || consequent instanceof AST_Assign)
if ((is_eq || consequent === seq_tail)
&& alt_tail instanceof AST_Assign
&& seq_tail.operator == alt_tail.operator
&& seq_tail.left.equivalent_to(alt_tail.left)
&& (!condition.has_side_effects(compressor)
|| is_eq && !seq_tail.left.has_side_effects(compressor))) {
&& (is_eq && !seq_tail.left.has_side_effects(compressor)
|| !condition.has_side_effects(compressor)
&& can_shift_lhs_of_tail(consequent)
&& can_shift_lhs_of_tail(alternative))) {
return make_node(AST_Assign, self, {
operator: seq_tail.operator,
left: seq_tail.left,
@@ -6221,6 +6223,19 @@ merge(Compressor.prototype, {
}
}
function can_shift_lhs_of_tail(node) {
if (node === node.tail_node()) return true;
var exprs = node.expressions;
for (var i = exprs.length - 1; --i >= 0;) {
var expr = exprs[i];
if (!(expr instanceof AST_Assign) && expr.has_side_effects(compressor)
|| expr.operator != "="
|| expr.left.has_side_effects(compressor)
|| expr.right.has_side_effects(compressor)) return false;
}
return true;
}
function pop_lhs(node) {
if (!(node instanceof AST_Sequence)) return node.right;
var exprs = node.expressions.slice();

View File

@@ -1384,3 +1384,34 @@ cond_seq_assign_3: {
}
expect_stdout: "2"
}
issue_3271: {
options = {
conditionals: true,
}
input: {
function f(a) {
var i = 0, b = [];
if (a) {
b[i++] = 4,
b[i++] = 1;
} else {
b[i++] = 3,
b[i++] = 2,
b[i++] = 1;
}
return b;
}
console.log(f(0).pop(), f(1).pop());
}
expect: {
function f(a) {
var i = 0, b = [];
a ? b[i++] = 4 : (b[i++] = 3, b[i++] = 2),
b[i++] = 1;
return b;
}
console.log(f(0).pop(), f(1).pop());
}
expect_stdout: "1 1"
}