enhance booleans & evaluate (#5364)
This commit is contained in:
@@ -11134,21 +11134,17 @@ Compressor.prototype.compress = function(node) {
|
||||
}
|
||||
if (in_bool) switch (self.operator) {
|
||||
case "+":
|
||||
var ll = self.left.evaluate(compressor);
|
||||
var rr = self.right.evaluate(compressor);
|
||||
if (ll && typeof ll == "string") {
|
||||
var ev = self.left.evaluate(compressor, true);
|
||||
if (ev && typeof ev == "string" || (ev = self.right.evaluate(compressor, true)) && typeof ev == "string") {
|
||||
AST_Node.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [
|
||||
self.right,
|
||||
make_node(AST_True, self)
|
||||
]).optimize(compressor);
|
||||
var exprs = [];
|
||||
if (self.left.evaluate(compressor) instanceof AST_Node) exprs.push(self.left);
|
||||
if (self.right.evaluate(compressor) instanceof AST_Node) exprs.push(self.right);
|
||||
if (exprs.length < 2) {
|
||||
exprs.push(make_node(AST_True, self));
|
||||
return make_sequence(self, exprs).optimize(compressor);
|
||||
}
|
||||
if (rr && typeof rr == "string") {
|
||||
AST_Node.warn("+ in boolean context always true [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [
|
||||
self.left,
|
||||
make_node(AST_True, self)
|
||||
]).optimize(compressor);
|
||||
self.truthy = true;
|
||||
}
|
||||
break;
|
||||
case "==":
|
||||
@@ -11231,21 +11227,16 @@ Compressor.prototype.compress = function(node) {
|
||||
AST_Node.warn("Condition left of && always true [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [ self.left, self.right ]).optimize(compressor);
|
||||
}
|
||||
var rr = self.right.evaluate(compressor);
|
||||
if (!rr) {
|
||||
if (in_bool) {
|
||||
if (!self.right.evaluate(compressor, true)) {
|
||||
if (in_bool && !(self.right.evaluate(compressor) instanceof AST_Node)) {
|
||||
AST_Node.warn("Boolean && always false [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [
|
||||
self.left,
|
||||
make_node(AST_False, self)
|
||||
]).optimize(compressor);
|
||||
return make_sequence(self, [ self.left, make_node(AST_False, self) ]).optimize(compressor);
|
||||
} else self.falsy = true;
|
||||
} else if (!(rr instanceof AST_Node)) {
|
||||
if (in_bool || parent.operator == "&&" && parent.left === compressor.self()) {
|
||||
} else if ((in_bool || parent.operator == "&&" && parent.left === compressor.self())
|
||||
&& !(self.right.evaluate(compressor) instanceof AST_Node)) {
|
||||
AST_Node.warn("Dropping side-effect-free && [{file}:{line},{col}]", self.start);
|
||||
return self.left.optimize(compressor);
|
||||
}
|
||||
}
|
||||
// (x || false) && y ---> x ? y : false
|
||||
if (self.left.operator == "||") {
|
||||
var lr = fuzzy_eval(compressor, self.left.right);
|
||||
@@ -11279,9 +11270,14 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
return maintain_this_binding(compressor, parent, compressor.self(), self.left).optimize(compressor);
|
||||
}
|
||||
var rr = self.right.evaluate(compressor);
|
||||
if (!rr) {
|
||||
if (in_bool || parent.operator == "||" && parent.left === compressor.self()) {
|
||||
var rr;
|
||||
if (!nullish && (rr = self.right.evaluate(compressor, true)) && !(rr instanceof AST_Node)) {
|
||||
if (in_bool && !(self.right.evaluate(compressor) instanceof AST_Node)) {
|
||||
AST_Node.warn("Boolean || always true [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [ self.left, make_node(AST_True, self) ]).optimize(compressor);
|
||||
} else self.truthy = true;
|
||||
} else if ((in_bool || parent.operator == "||" && parent.left === compressor.self())
|
||||
&& !self.right.evaluate(compressor)) {
|
||||
AST_Node.warn("Dropping side-effect-free {operator} [{file}:{line},{col}]", {
|
||||
operator: self.operator,
|
||||
file: self.start.file,
|
||||
@@ -11290,15 +11286,6 @@ Compressor.prototype.compress = function(node) {
|
||||
});
|
||||
return self.left.optimize(compressor);
|
||||
}
|
||||
} else if (!nullish && !(rr instanceof AST_Node)) {
|
||||
if (in_bool) {
|
||||
AST_Node.warn("Boolean || always true [{file}:{line},{col}]", self.start);
|
||||
return make_sequence(self, [
|
||||
self.left,
|
||||
make_node(AST_True, self)
|
||||
]).optimize(compressor);
|
||||
} else self.truthy = true;
|
||||
}
|
||||
// x && true || y ---> x ? true : y
|
||||
if (!nullish && self.left.operator == "&&") {
|
||||
var lr = fuzzy_eval(compressor, self.left.right);
|
||||
|
||||
@@ -427,6 +427,27 @@ negated_if: {
|
||||
expect_stdout: "PASS"
|
||||
}
|
||||
|
||||
concat_truthy: {
|
||||
options = {
|
||||
booleans: true,
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo") + (console.log("bar"), "baz") || console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo") + (console.log("bar"), "baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: + in boolean context always true [test/compress/booleans.js:1,8]",
|
||||
"WARN: Condition left of || always true [test/compress/booleans.js:1,8]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_3465_1: {
|
||||
options = {
|
||||
booleans: true,
|
||||
|
||||
@@ -888,6 +888,25 @@ unsafe_charAt_noop: {
|
||||
expect_stdout: "f n"
|
||||
}
|
||||
|
||||
chained_side_effects: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
}
|
||||
input: {
|
||||
console.log("foo") || (console.log("bar"), "baz") || console.log("moo");
|
||||
}
|
||||
expect: {
|
||||
console.log("foo") || (console.log("bar"), "baz");
|
||||
}
|
||||
expect_stdout: [
|
||||
"foo",
|
||||
"bar",
|
||||
]
|
||||
expect_warnings: [
|
||||
"WARN: Condition left of || always true [test/compress/evaluate.js:1,8]",
|
||||
]
|
||||
}
|
||||
|
||||
issue_1649: {
|
||||
options = {
|
||||
evaluate: true,
|
||||
|
||||
Reference in New Issue
Block a user