enhance conditionals (#3243)
This commit is contained in:
@@ -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
|
||||||
|
|||||||
@@ -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",
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user