enhance conditionals (#3694)
This commit is contained in:
@@ -7194,23 +7194,24 @@ merge(Compressor.prototype, {
|
|||||||
expressions.push(self);
|
expressions.push(self);
|
||||||
return make_sequence(self, expressions);
|
return make_sequence(self, expressions);
|
||||||
}
|
}
|
||||||
var cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
|
var condition = self.condition.is_truthy() || self.condition.evaluate(compressor);
|
||||||
if (!cond) {
|
if (!condition) {
|
||||||
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.start);
|
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.start);
|
||||||
return make_sequence(self, [ self.condition, self.alternative ]).optimize(compressor);
|
return make_sequence(self, [ self.condition, self.alternative ]).optimize(compressor);
|
||||||
} else if (!(cond instanceof AST_Node)) {
|
} else if (!(condition instanceof AST_Node)) {
|
||||||
AST_Node.warn("Condition always true [{file}:{line},{col}]", self.start);
|
AST_Node.warn("Condition always true [{file}:{line},{col}]", self.start);
|
||||||
return make_sequence(self, [ self.condition, self.consequent ]).optimize(compressor);
|
return make_sequence(self, [ self.condition, self.consequent ]).optimize(compressor);
|
||||||
}
|
}
|
||||||
var negated = cond.negate(compressor, first_in_statement(compressor));
|
var negated = condition.negate(compressor, first_in_statement(compressor));
|
||||||
if (best_of(compressor, cond, negated) === negated) {
|
if (best_of(compressor, condition, negated) === negated) {
|
||||||
self = make_node(AST_Conditional, self, {
|
self = make_node(AST_Conditional, self, {
|
||||||
condition: negated,
|
condition: negated,
|
||||||
consequent: self.alternative,
|
consequent: self.alternative,
|
||||||
alternative: self.consequent
|
alternative: self.consequent
|
||||||
});
|
});
|
||||||
|
negated = condition;
|
||||||
|
condition = self.condition;
|
||||||
}
|
}
|
||||||
var condition = self.condition;
|
|
||||||
var consequent = self.consequent;
|
var consequent = self.consequent;
|
||||||
var alternative = self.alternative;
|
var alternative = self.alternative;
|
||||||
// x ? x : y => x || y
|
// x ? x : y => x || y
|
||||||
@@ -7298,6 +7299,19 @@ merge(Compressor.prototype, {
|
|||||||
alternative: alternative
|
alternative: alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
// x ? (y ? a : b) : a => !x || y ? a : b
|
||||||
|
if (consequent instanceof AST_Conditional
|
||||||
|
&& consequent.consequent.equivalent_to(alternative)) {
|
||||||
|
return make_node(AST_Conditional, self, {
|
||||||
|
condition: make_node(AST_Binary, self, {
|
||||||
|
left: negated,
|
||||||
|
operator: "||",
|
||||||
|
right: consequent.condition
|
||||||
|
}),
|
||||||
|
consequent: alternative,
|
||||||
|
alternative: consequent.alternative
|
||||||
|
});
|
||||||
|
}
|
||||||
// x ? a : (y ? a : b) => x || y ? a : b
|
// x ? a : (y ? a : b) => x || y ? a : b
|
||||||
if (alternative instanceof AST_Conditional
|
if (alternative instanceof AST_Conditional
|
||||||
&& consequent.equivalent_to(alternative.consequent)) {
|
&& consequent.equivalent_to(alternative.consequent)) {
|
||||||
@@ -7311,7 +7325,20 @@ merge(Compressor.prototype, {
|
|||||||
alternative: alternative.alternative
|
alternative: alternative.alternative
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
// x ? (y, w) : (z, w) => x ? y : z, w
|
// x ? b : (y ? a : b) => !x && y ? a : b
|
||||||
|
if (alternative instanceof AST_Conditional
|
||||||
|
&& consequent.equivalent_to(alternative.alternative)) {
|
||||||
|
return make_node(AST_Conditional, self, {
|
||||||
|
condition: make_node(AST_Binary, self, {
|
||||||
|
left: negated,
|
||||||
|
operator: "&&",
|
||||||
|
right: alternative.condition
|
||||||
|
}),
|
||||||
|
consequent: alternative.consequent,
|
||||||
|
alternative: consequent
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// x ? (a, c) : (b, c) => x ? a : b, c
|
||||||
if ((consequent instanceof AST_Sequence || alternative instanceof AST_Sequence)
|
if ((consequent instanceof AST_Sequence || alternative instanceof AST_Sequence)
|
||||||
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
|
||||||
return make_sequence(self, [
|
return make_sequence(self, [
|
||||||
@@ -7323,7 +7350,21 @@ merge(Compressor.prototype, {
|
|||||||
consequent.tail_node()
|
consequent.tail_node()
|
||||||
]).optimize(compressor);
|
]).optimize(compressor);
|
||||||
}
|
}
|
||||||
// x ? y || z : z => x && y || z
|
// x ? y && a : a => (!x || y) && a
|
||||||
|
if (consequent instanceof AST_Binary
|
||||||
|
&& consequent.operator == "&&"
|
||||||
|
&& consequent.right.equivalent_to(alternative)) {
|
||||||
|
return make_node(AST_Binary, self, {
|
||||||
|
operator: "&&",
|
||||||
|
left: make_node(AST_Binary, self, {
|
||||||
|
operator: "||",
|
||||||
|
left: negated,
|
||||||
|
right: consequent.left
|
||||||
|
}),
|
||||||
|
right: alternative
|
||||||
|
}).optimize(compressor);
|
||||||
|
}
|
||||||
|
// x ? y || a : a => x && y || a
|
||||||
if (consequent instanceof AST_Binary
|
if (consequent instanceof AST_Binary
|
||||||
&& consequent.operator == "||"
|
&& consequent.operator == "||"
|
||||||
&& consequent.right.equivalent_to(alternative)) {
|
&& consequent.right.equivalent_to(alternative)) {
|
||||||
@@ -7337,6 +7378,34 @@ merge(Compressor.prototype, {
|
|||||||
right: alternative
|
right: alternative
|
||||||
}).optimize(compressor);
|
}).optimize(compressor);
|
||||||
}
|
}
|
||||||
|
// x ? a : y && a => (x || y) && a
|
||||||
|
if (alternative instanceof AST_Binary
|
||||||
|
&& alternative.operator == "&&"
|
||||||
|
&& alternative.right.equivalent_to(consequent)) {
|
||||||
|
return make_node(AST_Binary, self, {
|
||||||
|
operator: "&&",
|
||||||
|
left: make_node(AST_Binary, self, {
|
||||||
|
operator: "||",
|
||||||
|
left: condition,
|
||||||
|
right: alternative.left
|
||||||
|
}),
|
||||||
|
right: consequent
|
||||||
|
}).optimize(compressor);
|
||||||
|
}
|
||||||
|
// x ? a : y || a => !x && y || a
|
||||||
|
if (alternative instanceof AST_Binary
|
||||||
|
&& alternative.operator == "||"
|
||||||
|
&& alternative.right.equivalent_to(consequent)) {
|
||||||
|
return make_node(AST_Binary, self, {
|
||||||
|
operator: "||",
|
||||||
|
left: make_node(AST_Binary, self, {
|
||||||
|
operator: "&&",
|
||||||
|
left: negated,
|
||||||
|
right: alternative.left
|
||||||
|
}),
|
||||||
|
right: consequent
|
||||||
|
}).optimize(compressor);
|
||||||
|
}
|
||||||
var in_bool = compressor.option("booleans") && compressor.in_boolean_context();
|
var in_bool = compressor.option("booleans") && compressor.in_boolean_context();
|
||||||
if (is_true(consequent)) {
|
if (is_true(consequent)) {
|
||||||
if (is_false(alternative)) {
|
if (is_false(alternative)) {
|
||||||
|
|||||||
@@ -294,6 +294,45 @@ cond_5: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_6: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x ? a : b;
|
||||||
|
x ? a : a;
|
||||||
|
|
||||||
|
x ? y ? a : b : c;
|
||||||
|
x ? y ? a : a : b;
|
||||||
|
x ? y ? a : b : b;
|
||||||
|
x ? y ? a : b : a;
|
||||||
|
x ? y ? a : a : a;
|
||||||
|
|
||||||
|
x ? a : y ? b : c;
|
||||||
|
x ? a : y ? a : b;
|
||||||
|
x ? a : y ? b : b;
|
||||||
|
x ? a : y ? b : a;
|
||||||
|
x ? a : y ? a : a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
x ? a : b;
|
||||||
|
x, a;
|
||||||
|
|
||||||
|
x ? y ? a : b : c;
|
||||||
|
x ? (y, a) : b;
|
||||||
|
x && y ? a : b;
|
||||||
|
!x || y ? a : b;
|
||||||
|
x && y, a;
|
||||||
|
|
||||||
|
x ? a : y ? b : c;
|
||||||
|
x || y ? a : b;
|
||||||
|
x ? a : (y, b);
|
||||||
|
!x && y ? b : a;
|
||||||
|
!x && y, a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
cond_7: {
|
cond_7: {
|
||||||
options = {
|
options = {
|
||||||
conditionals: true,
|
conditionals: true,
|
||||||
@@ -726,6 +765,24 @@ cond_11: {
|
|||||||
expect_stdout: "foo bar"
|
expect_stdout: "foo bar"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cond_12: {
|
||||||
|
options = {
|
||||||
|
conditionals: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
x ? y && a : a;
|
||||||
|
x ? y || a : a;
|
||||||
|
x ? a : y && a;
|
||||||
|
x ? a : y || a;
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
(!x || y) && a;
|
||||||
|
x && y || a;
|
||||||
|
(x || y) && a;
|
||||||
|
!x && y || a;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ternary_boolean_consequent: {
|
ternary_boolean_consequent: {
|
||||||
options = {
|
options = {
|
||||||
booleans: true,
|
booleans: true,
|
||||||
|
|||||||
Reference in New Issue
Block a user