aboutsummaryrefslogtreecommitdiff
path: root/lib/compress.js
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-09-15 22:51:42 +0100
committerGitHub <noreply@github.com>2020-09-16 05:51:42 +0800
commit20391850518f4050917a4812af07520eb47cfecf (patch)
treec1bd66edfb47f36988052472bde677497da4b082 /lib/compress.js
parentad27c1420226032459157444cf7ac17bf95bd5e6 (diff)
downloadtracifyjs-20391850518f4050917a4812af07520eb47cfecf.tar.gz
tracifyjs-20391850518f4050917a4812af07520eb47cfecf.zip
enhance `conditionals` (#4106)
Diffstat (limited to 'lib/compress.js')
-rw-r--r--lib/compress.js79
1 files changed, 49 insertions, 30 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 52ed0e61..dbf4e09d 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -8456,35 +8456,26 @@ merge(Compressor.prototype, {
condition,
consequent
]).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
- && alternative.TYPE === consequent.TYPE
- && consequent.args.length == alternative.args.length) {
- var arg_index = arg_diff();
- // x ? y(a) : z(a) => (x ? y : z)(a)
- if (arg_index == -1
- && !(consequent.expression instanceof AST_PropAccess)
- && !(alternative.expression instanceof AST_PropAccess)) {
- var node = consequent.clone();
- node.expression = make_node(AST_Conditional, self, {
- condition: condition,
- consequent: consequent.expression,
- alternative: alternative.expression
- });
- 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;
- }
+ && alternative.TYPE == consequent.TYPE
+ && (arg_index = arg_diff(consequent, alternative)) >= 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
if (consequent instanceof AST_Conditional
@@ -8685,10 +8676,12 @@ merge(Compressor.prototype, {
&& node.expression.value);
}
- function arg_diff() {
+ function arg_diff(consequent, alternative) {
var a = consequent.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])) {
for (var j = i + 1; j < len; j++) {
if (!a[j].equivalent_to(b[j])) return -2;
@@ -8699,6 +8692,32 @@ merge(Compressor.prototype, {
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) {
return node === node.tail_node() || all(node.expressions.slice(0, -1), function(expr) {
return !expr.has_side_effects(compressor);