aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-01-28 12:33:21 +0800
committerGitHub <noreply@github.com>2020-01-28 12:33:21 +0800
commitb499e03f82987d59814c81fb9f211fee5e3a7ba4 (patch)
tree2f7b22c777dea6822cfa416fc3e41cd83b8bdeb5 /lib
parenta478f275e421ccbb428f38272e8e673f6684729c (diff)
downloadtracifyjs-b499e03f82987d59814c81fb9f211fee5e3a7ba4.tar.gz
tracifyjs-b499e03f82987d59814c81fb9f211fee5e3a7ba4.zip
enhance `conditionals` (#3694)
Diffstat (limited to 'lib')
-rw-r--r--lib/compress.js85
1 files changed, 77 insertions, 8 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 2a338ba1..f2dfb64c 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -7194,23 +7194,24 @@ merge(Compressor.prototype, {
expressions.push(self);
return make_sequence(self, expressions);
}
- var cond = self.condition.is_truthy() || self.condition.tail_node().evaluate(compressor);
- if (!cond) {
+ var condition = self.condition.is_truthy() || self.condition.evaluate(compressor);
+ if (!condition) {
AST_Node.warn("Condition always false [{file}:{line},{col}]", self.start);
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);
return make_sequence(self, [ self.condition, self.consequent ]).optimize(compressor);
}
- var negated = cond.negate(compressor, first_in_statement(compressor));
- if (best_of(compressor, cond, negated) === negated) {
+ var negated = condition.negate(compressor, first_in_statement(compressor));
+ if (best_of(compressor, condition, negated) === negated) {
self = make_node(AST_Conditional, self, {
condition: negated,
consequent: self.alternative,
alternative: self.consequent
});
+ negated = condition;
+ condition = self.condition;
}
- var condition = self.condition;
var consequent = self.consequent;
var alternative = self.alternative;
// x ? x : y => x || y
@@ -7298,6 +7299,19 @@ merge(Compressor.prototype, {
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
if (alternative instanceof AST_Conditional
&& consequent.equivalent_to(alternative.consequent)) {
@@ -7311,7 +7325,20 @@ merge(Compressor.prototype, {
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)
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
return make_sequence(self, [
@@ -7323,7 +7350,21 @@ merge(Compressor.prototype, {
consequent.tail_node()
]).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
&& consequent.operator == "||"
&& consequent.right.equivalent_to(alternative)) {
@@ -7337,6 +7378,34 @@ merge(Compressor.prototype, {
right: alternative
}).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();
if (is_true(consequent)) {
if (is_false(alternative)) {