enhance conditionals (#3243)

This commit is contained in:
Alex Lam S.L
2018-08-30 01:06:34 +08:00
committed by GitHub
parent aa0029204e
commit 2bdaca10ae
2 changed files with 105 additions and 24 deletions

View File

@@ -6047,20 +6047,22 @@ merge(Compressor.prototype, {
// | // |
// v // v
// exp = foo ? something : something_else; // exp = foo ? something : something_else;
if (consequent instanceof AST_Assign var seq_tail = consequent.tail_node();
&& alternative instanceof AST_Assign var alt_tail = alternative.tail_node();
&& consequent.operator == alternative.operator if (seq_tail instanceof AST_Assign
&& consequent.left.equivalent_to(alternative.left) && alt_tail instanceof AST_Assign
&& (!self.condition.has_side_effects(compressor) && seq_tail.operator == alt_tail.operator
|| consequent.operator == "=" && seq_tail.left.equivalent_to(alt_tail.left)
&& !consequent.left.has_side_effects(compressor))) { && (!condition.has_side_effects(compressor)
|| seq_tail.operator == "="
&& !seq_tail.left.has_side_effects(compressor))) {
return make_node(AST_Assign, self, { return make_node(AST_Assign, self, {
operator: consequent.operator, operator: seq_tail.operator,
left: consequent.left, left: seq_tail.left,
right: make_node(AST_Conditional, self, { right: make_node(AST_Conditional, self, {
condition: self.condition, condition: condition,
consequent: consequent.right, consequent: pop_lhs(consequent),
alternative: alternative.right alternative: pop_lhs(alternative)
}) })
}); });
} }
@@ -6071,12 +6073,12 @@ merge(Compressor.prototype, {
&& consequent.args.length > 0 && consequent.args.length > 0
&& consequent.args.length == alternative.args.length && consequent.args.length == alternative.args.length
&& consequent.expression.equivalent_to(alternative.expression) && consequent.expression.equivalent_to(alternative.expression)
&& !self.condition.has_side_effects(compressor) && !condition.has_side_effects(compressor)
&& !consequent.expression.has_side_effects(compressor) && !consequent.expression.has_side_effects(compressor)
&& typeof (arg_index = single_arg_diff()) == "number") { && typeof (arg_index = single_arg_diff()) == "number") {
var node = consequent.clone(); var node = consequent.clone();
node.args[arg_index] = make_node(AST_Conditional, self, { node.args[arg_index] = make_node(AST_Conditional, self, {
condition: self.condition, condition: condition,
consequent: consequent.args[arg_index], consequent: consequent.args[arg_index],
alternative: alternative.args[arg_index] alternative: alternative.args[arg_index]
}); });
@@ -6087,7 +6089,7 @@ merge(Compressor.prototype, {
&& consequent.alternative.equivalent_to(alternative)) { && consequent.alternative.equivalent_to(alternative)) {
return make_node(AST_Conditional, self, { return make_node(AST_Conditional, self, {
condition: make_node(AST_Binary, self, { condition: make_node(AST_Binary, self, {
left: self.condition, left: condition,
operator: "&&", operator: "&&",
right: consequent.condition right: consequent.condition
}), }),
@@ -6098,7 +6100,7 @@ merge(Compressor.prototype, {
// x ? y : y --> x, y // x ? y : y --> x, y
if (consequent.equivalent_to(alternative)) { if (consequent.equivalent_to(alternative)) {
return make_sequence(self, [ return make_sequence(self, [
self.condition, condition,
consequent consequent
]).optimize(compressor); ]).optimize(compressor);
} }
@@ -6107,7 +6109,7 @@ merge(Compressor.prototype, {
&& consequent.tail_node().equivalent_to(alternative.tail_node())) { && consequent.tail_node().equivalent_to(alternative.tail_node())) {
return make_sequence(self, [ return make_sequence(self, [
make_node(AST_Conditional, self, { make_node(AST_Conditional, self, {
condition: self.condition, condition: condition,
consequent: pop_seq(consequent), consequent: pop_seq(consequent),
alternative: pop_seq(alternative) alternative: pop_seq(alternative)
}), }),
@@ -6122,7 +6124,7 @@ merge(Compressor.prototype, {
operator: "||", operator: "||",
left: make_node(AST_Binary, self, { left: make_node(AST_Binary, self, {
operator: "&&", operator: "&&",
left: self.condition, left: condition,
right: consequent.left right: consequent.left
}), }),
right: alternative right: alternative
@@ -6132,24 +6134,24 @@ merge(Compressor.prototype, {
if (is_true(self.consequent)) { if (is_true(self.consequent)) {
if (is_false(self.alternative)) { if (is_false(self.alternative)) {
// c ? true : false ---> !!c // c ? true : false ---> !!c
return booleanize(self.condition); return booleanize(condition);
} }
// c ? true : x ---> !!c || x // c ? true : x ---> !!c || x
return make_node(AST_Binary, self, { return make_node(AST_Binary, self, {
operator: "||", operator: "||",
left: booleanize(self.condition), left: booleanize(condition),
right: self.alternative right: self.alternative
}); });
} }
if (is_false(self.consequent)) { if (is_false(self.consequent)) {
if (is_true(self.alternative)) { if (is_true(self.alternative)) {
// c ? false : true ---> !c // c ? false : true ---> !c
return booleanize(self.condition.negate(compressor)); return booleanize(condition.negate(compressor));
} }
// c ? false : x ---> !c && x // c ? false : x ---> !c && x
return make_node(AST_Binary, self, { return make_node(AST_Binary, self, {
operator: "&&", operator: "&&",
left: booleanize(self.condition.negate(compressor)), left: booleanize(condition.negate(compressor)),
right: self.alternative right: self.alternative
}); });
} }
@@ -6157,7 +6159,7 @@ merge(Compressor.prototype, {
// c ? x : true ---> !c || x // c ? x : true ---> !c || x
return make_node(AST_Binary, self, { return make_node(AST_Binary, self, {
operator: "||", operator: "||",
left: booleanize(self.condition.negate(compressor)), left: booleanize(condition.negate(compressor)),
right: self.consequent right: self.consequent
}); });
} }
@@ -6165,7 +6167,7 @@ merge(Compressor.prototype, {
// c ? x : false ---> !!c && x // c ? x : false ---> !!c && x
return make_node(AST_Binary, self, { return make_node(AST_Binary, self, {
operator: "&&", operator: "&&",
left: booleanize(self.condition), left: booleanize(condition),
right: self.consequent right: self.consequent
}); });
} }
@@ -6217,6 +6219,13 @@ merge(Compressor.prototype, {
} }
} }
function pop_lhs(node) {
if (!(node instanceof AST_Sequence)) return node.right;
var exprs = node.expressions.slice();
exprs.push(exprs.pop().right);
return make_sequence(node, exprs);
}
function pop_seq(node) { function pop_seq(node) {
if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, { if (!(node instanceof AST_Sequence)) return make_node(AST_Number, node, {
value: 0 value: 0

View File

@@ -1292,3 +1292,75 @@ to_and_or: {
} }
expect_stdout: true expect_stdout: true
} }
cond_seq_assign_1: {
options = {
conditionals: true,
sequences: true,
}
input: {
function f(a) {
var t;
if (a) {
t = "foo";
t = "bar";
} else {
console.log(t);
t = 42;
}
console.log(t);
}
f(f);
f();
}
expect: {
function f(a) {
var t;
t = a ? (t = "foo", "bar") : (console.log(t), 42),
console.log(t);
}
f(f),
f();
}
expect_stdout: [
"bar",
"undefined",
"42",
]
}
cond_seq_assign_2: {
options = {
conditionals: true,
sequences: true,
}
input: {
function f(a) {
var t;
if (a) {
t = "foo";
a = "bar";
} else {
console.log(t);
t = 42;
}
console.log(t);
}
f(f);
f();
}
expect: {
function f(a) {
var t;
a ? (t = "foo", a = "bar") : (console.log(t), t = 42),
console.log(t);
}
f(f),
f();
}
expect_stdout: [
"foo",
"undefined",
"42",
]
}