enhance conditionals (#4106)

This commit is contained in:
Alex Lam S.L
2020-09-15 22:51:42 +01:00
committed by GitHub
parent ad27c14202
commit 2039185051
2 changed files with 71 additions and 30 deletions

View File

@@ -8456,35 +8456,26 @@ merge(Compressor.prototype, {
condition, condition,
consequent consequent
]).optimize(compressor); ]).optimize(compressor);
// x ? y.p : z.p => (x ? y : z).p
// x ? y(a) : z(a) => (x ? y : z)(a)
// x ? y.f(a) : z.f(a) => (x ? y : z).f(a)
var combined = combine_tail(consequent, alternative, true);
if (combined) return combined;
// x ? y(a) : y(b) => y(x ? a : b)
var arg_index;
if (consequent instanceof AST_Call if (consequent instanceof AST_Call
&& alternative.TYPE === consequent.TYPE && alternative.TYPE == consequent.TYPE
&& consequent.args.length == alternative.args.length) { && (arg_index = arg_diff(consequent, alternative)) >= 0
var arg_index = arg_diff(); && consequent.expression.equivalent_to(alternative.expression)
// x ? y(a) : z(a) => (x ? y : z)(a) && !condition.has_side_effects(compressor)
if (arg_index == -1 && !consequent.expression.has_side_effects(compressor)) {
&& !(consequent.expression instanceof AST_PropAccess) var node = consequent.clone();
&& !(alternative.expression instanceof AST_PropAccess)) { node.args[arg_index] = make_node(AST_Conditional, self, {
var node = consequent.clone(); condition: condition,
node.expression = make_node(AST_Conditional, self, { consequent: consequent.args[arg_index],
condition: condition, alternative: alternative.args[arg_index]
consequent: consequent.expression, });
alternative: alternative.expression return node;
});
return node;
}
// x ? y(a) : y(b) => y(x ? a : b)
if (arg_index >= 0
&& consequent.expression.equivalent_to(alternative.expression)
&& !condition.has_side_effects(compressor)
&& !consequent.expression.has_side_effects(compressor)) {
var node = consequent.clone();
node.args[arg_index] = make_node(AST_Conditional, self, {
condition: condition,
consequent: consequent.args[arg_index],
alternative: alternative.args[arg_index]
});
return node;
}
} }
// x ? (y ? a : b) : b => x && y ? a : b // x ? (y ? a : b) : b => x && y ? a : b
if (consequent instanceof AST_Conditional if (consequent instanceof AST_Conditional
@@ -8685,10 +8676,12 @@ merge(Compressor.prototype, {
&& node.expression.value); && node.expression.value);
} }
function arg_diff() { function arg_diff(consequent, alternative) {
var a = consequent.args; var a = consequent.args;
var b = alternative.args; var b = alternative.args;
for (var i = 0, len = a.length; i < len; i++) { var len = a.length;
if (len != b.length) return -2;
for (var i = 0; i < len; i++) {
if (!a[i].equivalent_to(b[i])) { if (!a[i].equivalent_to(b[i])) {
for (var j = i + 1; j < len; j++) { for (var j = i + 1; j < len; j++) {
if (!a[j].equivalent_to(b[j])) return -2; if (!a[j].equivalent_to(b[j])) return -2;
@@ -8699,6 +8692,32 @@ merge(Compressor.prototype, {
return -1; return -1;
} }
function is_tail_equivalent(consequent, alternative) {
if (consequent.TYPE != alternative.TYPE) return;
if (consequent instanceof AST_Call) {
if (arg_diff(consequent, alternative) != -1) return;
return consequent.TYPE != "Call"
|| !(consequent.expression instanceof AST_PropAccess
|| alternative.expression instanceof AST_PropAccess)
|| is_tail_equivalent(consequent.expression, alternative.expression);
}
if (consequent instanceof AST_Dot) return consequent.property == alternative.property;
if (consequent instanceof AST_Sub) return consequent.property.equivalent_to(alternative.property);
}
function combine_tail(consequent, alternative, top) {
if (!is_tail_equivalent(consequent, alternative)) return !top && make_node(AST_Conditional, self, {
condition: condition,
consequent: consequent,
alternative: alternative
});
var exp = combine_tail(consequent.expression, alternative.expression);
if (!exp) return;
var node = consequent.clone();
node.expression = exp;
return node;
}
function can_shift_lhs_of_tail(node) { function can_shift_lhs_of_tail(node) {
return node === node.tail_node() || all(node.expressions.slice(0, -1), function(expr) { return node === node.tail_node() || all(node.expressions.slice(0, -1), function(expr) {
return !expr.has_side_effects(compressor); return !expr.has_side_effects(compressor);

View File

@@ -783,6 +783,28 @@ cond_12: {
} }
} }
cond_13: {
options = {
conditionals: true,
}
input: {
x ? y(a) : z(a);
x ? y.f(a) : z.f(a);
x ? y.f(a) : z.g(a);
x ? y.f()(a) : z.g()(a);
x ? y.f.u(a) : z.g.u(a);
x ? y.f().u(a) : z.g().u(a);
}
expect: {
(x ? y : z)(a);
(x ? y : z).f(a);
x ? y.f(a) : z.g(a);
(x ? y.f() : z.g())(a);
(x ? y.f : z.g).u(a);
(x ? y.f() : z.g()).u(a);
}
}
ternary_boolean_consequent: { ternary_boolean_consequent: {
options = { options = {
booleans: true, booleans: true,