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