aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-12-31 11:51:21 +0800
committerGitHub <noreply@github.com>2019-12-31 11:51:21 +0800
commita2e4c2fd979782c1dd526fc1ac0b14490adb3344 (patch)
treed1335eeb561a00d7784af0a0566788c2fb9e5f5b
parent94785e8e14efaba6b2d8cbe61f183cf920cdb329 (diff)
downloadtracifyjs-a2e4c2fd979782c1dd526fc1ac0b14490adb3344.tar.gz
tracifyjs-a2e4c2fd979782c1dd526fc1ac0b14490adb3344.zip
enhance `evaluate` (#3660)
-rw-r--r--lib/compress.js57
1 files changed, 29 insertions, 28 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 76ad3996..3f6bc893 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2023,7 +2023,7 @@ merge(Compressor.prototype, {
var value = stat.body.value;
//---
// pretty silly case, but:
- // if (foo()) return; return; ==> foo(); return;
+ // if (foo()) return; return; => foo(); return;
if (!value && !stat.alternative
&& (in_lambda && !next || next instanceof AST_Return && !next.value)) {
CHANGED = true;
@@ -2033,7 +2033,7 @@ merge(Compressor.prototype, {
continue;
}
//---
- // if (foo()) return x; return y; ==> return foo() ? x : y;
+ // if (foo()) return x; return y; => return foo() ? x : y;
if (value && !stat.alternative && next instanceof AST_Return && next.value) {
CHANGED = true;
stat = stat.clone();
@@ -2043,7 +2043,7 @@ merge(Compressor.prototype, {
continue;
}
//---
- // if (foo()) return x; [ return ; ] ==> return foo() ? x : undefined;
+ // if (foo()) return x; [ return ; ] => return foo() ? x : undefined;
if (value && !stat.alternative
&& (!next && in_lambda && multiple_if_returns
|| next instanceof AST_Return)) {
@@ -2057,7 +2057,7 @@ merge(Compressor.prototype, {
continue;
}
//---
- // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e;
+ // if (a) return b; if (c) return d; e; => return a ? b : c ? d : void e;
//
// if sequences is not enabled, this can lead to an endless loop (issue #866).
// however, with sequences on this helps producing slightly better output for
@@ -6025,7 +6025,7 @@ merge(Compressor.prototype, {
} else if (compressor.in_boolean_context()) switch (self.operator) {
case "!":
if (e instanceof AST_UnaryPrefix && e.operator == "!") {
- // !!foo ==> foo, if we're in boolean context
+ // !!foo => foo, if we're in boolean context
return e.expression;
}
if (e instanceof AST_Binary) {
@@ -6317,9 +6317,9 @@ merge(Compressor.prototype, {
return self.left.optimize(compressor);
}
}
- // x || false && y ---> x ? y : false
+ // (x || false) && y => x ? y : false
if (self.left.operator == "||") {
- var lr = self.left.right.evaluate(compressor);
+ var lr = self.left.right.tail_node().evaluate(compressor);
if (!lr) return make_node(AST_Conditional, self, {
condition: self.left.left,
consequent: self.right,
@@ -6351,8 +6351,9 @@ merge(Compressor.prototype, {
]).optimize(compressor);
} else self.truthy = true;
}
+ // x && true || y => x ? true : y
if (self.left.operator == "&&") {
- var lr = self.left.right.evaluate(compressor);
+ var lr = self.left.right.is_truthy() || self.left.right.tail_node().evaluate(compressor);
if (lr && !(lr instanceof AST_Node)) return make_node(AST_Conditional, self, {
condition: self.left.left,
consequent: self.left.right,
@@ -6650,10 +6651,10 @@ merge(Compressor.prototype, {
return node.optimize(compressor);
}
}
- // x && (y && z) ==> x && y && z
- // x || (y || z) ==> x || y || z
- // x + ("y" + z) ==> x + "y" + z
- // "x" + (y + "z")==> "x" + y + "z"
+ // x && (y && z) => x && y && z
+ // x || (y || z) => x || y || z
+ // x + ("y" + z) => x + "y" + z
+ // "x" + (y + "z") => "x" + y + "z"
if (self.right instanceof AST_Binary
&& self.right.operator == self.operator
&& (lazy_op[self.operator]
@@ -7055,7 +7056,7 @@ merge(Compressor.prototype, {
if (self.right.left instanceof AST_SymbolRef
&& self.right.left.name == self.left.name
&& ASSIGN_OPS[self.right.operator]) {
- // x = x - 2 ---> x -= 2
+ // x = x - 2 => x -= 2
self.operator = self.right.operator + "=";
self.right = self.right.right;
}
@@ -7063,7 +7064,7 @@ merge(Compressor.prototype, {
&& self.right.right.name == self.left.name
&& ASSIGN_OPS_COMMUTATIVE[self.right.operator]
&& !self.right.left.has_side_effects(compressor)) {
- // x = 2 & x ---> x &= 2
+ // x = 2 & x => x &= 2
self.operator = self.right.operator + "=";
self.right = self.right.left;
}
@@ -7132,7 +7133,7 @@ merge(Compressor.prototype, {
var condition = self.condition;
var consequent = self.consequent;
var alternative = self.alternative;
- // x?x:y --> x||y
+ // x ? x : y => x || y
if (condition instanceof AST_SymbolRef
&& consequent instanceof AST_SymbolRef
&& condition.definition() === consequent.definition()) {
@@ -7169,7 +7170,7 @@ merge(Compressor.prototype, {
});
}
}
- // x ? y : y --> x, y
+ // x ? y : y => x, y
if (consequent.equivalent_to(alternative)) return make_sequence(self, [
condition,
consequent
@@ -7178,7 +7179,7 @@ merge(Compressor.prototype, {
&& alternative.TYPE === consequent.TYPE
&& consequent.args.length == alternative.args.length) {
var arg_index = arg_diff();
- // x ? y(a) : z(a) --> (x ? y : z)(a)
+ // x ? y(a) : z(a) => (x ? y : z)(a)
if (arg_index == -1
&& !(consequent.expression instanceof AST_PropAccess)
&& !(alternative.expression instanceof AST_PropAccess)) {
@@ -7190,7 +7191,7 @@ merge(Compressor.prototype, {
});
return node;
}
- // x ? y(a) : y(b) --> y(x ? a : b)
+ // x ? y(a) : y(b) => y(x ? a : b)
if (arg_index >= 0
&& consequent.expression.equivalent_to(alternative.expression)
&& !condition.has_side_effects(compressor)
@@ -7204,7 +7205,7 @@ merge(Compressor.prototype, {
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
&& consequent.alternative.equivalent_to(alternative)) {
return make_node(AST_Conditional, self, {
@@ -7217,7 +7218,7 @@ merge(Compressor.prototype, {
alternative: alternative
});
}
- // x ? a : (y ? a : b)--> x || y ? a : b
+ // x ? a : (y ? a : b) => x || y ? a : b
if (alternative instanceof AST_Conditional
&& consequent.equivalent_to(alternative.consequent)) {
return make_node(AST_Conditional, self, {
@@ -7230,7 +7231,7 @@ merge(Compressor.prototype, {
alternative: alternative.alternative
});
}
- // x ? (y, w) : (z, w) --> x ? y : z, w
+ // x ? (y, w) : (z, w) => x ? y : z, w
if ((consequent instanceof AST_Sequence || alternative instanceof AST_Sequence)
&& consequent.tail_node().equivalent_to(alternative.tail_node())) {
return make_sequence(self, [
@@ -7242,7 +7243,7 @@ merge(Compressor.prototype, {
consequent.tail_node()
]).optimize(compressor);
}
- // x ? y || z : z --> x && y || z
+ // x ? y || z : z => x && y || z
if (consequent instanceof AST_Binary
&& consequent.operator == "||"
&& consequent.right.equivalent_to(alternative)) {
@@ -7259,10 +7260,10 @@ merge(Compressor.prototype, {
var in_bool = compressor.option("booleans") && compressor.in_boolean_context();
if (is_true(consequent)) {
if (is_false(alternative)) {
- // c ? true : false ---> !!c
+ // c ? true : false => !!c
return booleanize(condition);
}
- // c ? true : x ---> !!c || x
+ // c ? true : x => !!c || x
return make_node(AST_Binary, self, {
operator: "||",
left: booleanize(condition),
@@ -7271,10 +7272,10 @@ merge(Compressor.prototype, {
}
if (is_false(consequent)) {
if (is_true(alternative)) {
- // c ? false : true ---> !c
+ // c ? false : true => !c
return booleanize(condition.negate(compressor));
}
- // c ? false : x ---> !c && x
+ // c ? false : x => !c && x
return make_node(AST_Binary, self, {
operator: "&&",
left: booleanize(condition.negate(compressor)),
@@ -7282,7 +7283,7 @@ merge(Compressor.prototype, {
});
}
if (is_true(alternative)) {
- // c ? x : true ---> !c || x
+ // c ? x : true => !c || x
return make_node(AST_Binary, self, {
operator: "||",
left: booleanize(condition.negate(compressor)),
@@ -7290,7 +7291,7 @@ merge(Compressor.prototype, {
});
}
if (is_false(alternative)) {
- // c ? x : false ---> !!c && x
+ // c ? x : false => !!c && x
return make_node(AST_Binary, self, {
operator: "&&",
left: booleanize(condition),