enhance unsafe comparisons (#3419)
This commit is contained in:
@@ -5969,11 +5969,10 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (compressor.option("unsafe")
|
if (compressor.option("unsafe")) {
|
||||||
&& self.right instanceof AST_Call
|
var indexRight = is_indexFn(self.right);
|
||||||
&& self.right.expression instanceof AST_Dot
|
|
||||||
&& indexFns[self.right.expression.property]) {
|
|
||||||
if (compressor.option("booleans")
|
if (compressor.option("booleans")
|
||||||
|
&& indexRight
|
||||||
&& (self.operator == "==" || self.operator == "!=")
|
&& (self.operator == "==" || self.operator == "!=")
|
||||||
&& self.left instanceof AST_Number
|
&& self.left instanceof AST_Number
|
||||||
&& self.left.getValue() == 0
|
&& self.left.getValue() == 0
|
||||||
@@ -5983,18 +5982,26 @@ merge(Compressor.prototype, {
|
|||||||
expression: self.right
|
expression: self.right
|
||||||
}) : self.right).optimize(compressor);
|
}) : self.right).optimize(compressor);
|
||||||
}
|
}
|
||||||
|
var indexLeft = is_indexFn(self.left);
|
||||||
if (compressor.option("comparisons") && is_indexOf_match_pattern()) {
|
if (compressor.option("comparisons") && is_indexOf_match_pattern()) {
|
||||||
var node = make_node(AST_UnaryPrefix, self, {
|
var node = make_node(AST_UnaryPrefix, self, {
|
||||||
operator: "!",
|
operator: "!",
|
||||||
expression: make_node(AST_UnaryPrefix, self, {
|
expression: make_node(AST_UnaryPrefix, self, {
|
||||||
operator: "~",
|
operator: "~",
|
||||||
expression: self.right
|
expression: indexLeft ? self.left : self.right
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
if (self.operator == "!=" || self.operator == "<=") node = make_node(AST_UnaryPrefix, self, {
|
switch (self.operator) {
|
||||||
|
case "<":
|
||||||
|
if (indexLeft) break;
|
||||||
|
case "<=":
|
||||||
|
case "!=":
|
||||||
|
node = make_node(AST_UnaryPrefix, self, {
|
||||||
operator: "!",
|
operator: "!",
|
||||||
expression: node
|
expression: node
|
||||||
});
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
return node.optimize(compressor);
|
return node.optimize(compressor);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -6032,17 +6039,26 @@ merge(Compressor.prototype, {
|
|||||||
return node.evaluate(compressor);
|
return node.evaluate(compressor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_indexFn(node) {
|
||||||
|
return node instanceof AST_Call
|
||||||
|
&& node.expression instanceof AST_Dot
|
||||||
|
&& indexFns[node.expression.property];
|
||||||
|
}
|
||||||
|
|
||||||
function is_indexOf_match_pattern() {
|
function is_indexOf_match_pattern() {
|
||||||
switch (self.operator) {
|
switch (self.operator) {
|
||||||
case ">":
|
|
||||||
case "<=":
|
case "<=":
|
||||||
// 0 > array.indexOf(string) => !~array.indexOf(string)
|
|
||||||
// 0 <= array.indexOf(string) => !!~array.indexOf(string)
|
// 0 <= array.indexOf(string) => !!~array.indexOf(string)
|
||||||
return self.left instanceof AST_Number && self.left.getValue() == 0;
|
return indexRight && self.left instanceof AST_Number && self.left.getValue() == 0;
|
||||||
|
case "<":
|
||||||
|
// array.indexOf(string) < 0 => !~array.indexOf(string)
|
||||||
|
if (indexLeft && self.right instanceof AST_Number && self.right.getValue() == 0) return true;
|
||||||
|
// -1 < array.indexOf(string) => !!~array.indexOf(string)
|
||||||
case "==":
|
case "==":
|
||||||
case "!=":
|
case "!=":
|
||||||
// -1 == array.indexOf(string) => !~array.indexOf(string)
|
// -1 == array.indexOf(string) => !~array.indexOf(string)
|
||||||
// -1 != array.indexOf(string) => !!~array.indexOf(string)
|
// -1 != array.indexOf(string) => !!~array.indexOf(string)
|
||||||
|
if (!indexRight) return false;
|
||||||
return self.left instanceof AST_Number && self.left.getValue() == -1
|
return self.left instanceof AST_Number && self.left.getValue() == -1
|
||||||
|| self.left instanceof AST_UnaryPrefix && self.left.operator == "-"
|
|| self.left instanceof AST_UnaryPrefix && self.left.operator == "-"
|
||||||
&& self.left.expression instanceof AST_Number && self.left.expression.getValue() == 1;
|
&& self.left.expression instanceof AST_Number && self.left.expression.getValue() == 1;
|
||||||
|
|||||||
@@ -373,12 +373,55 @@ unsafe_indexOf: {
|
|||||||
unsafe: true,
|
unsafe: true,
|
||||||
}
|
}
|
||||||
input: {
|
input: {
|
||||||
if (Object.keys({ foo: 42 }).indexOf("foo") >= 0) console.log("PASS");
|
var a = Object.keys({ foo: 42 });
|
||||||
|
if (a.indexOf("bar") < 0) console.log("PASS");
|
||||||
|
if (0 > a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") >= 0) console.log("PASS");
|
||||||
|
if (0 <= a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") > -1) console.log("PASS");
|
||||||
|
if (-1 < a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (a.indexOf("bar") == -1) console.log("PASS");
|
||||||
|
if (-1 == a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (a.indexOf("bar") === -1) console.log("PASS");
|
||||||
|
if (-1 === a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") != -1) console.log("PASS");
|
||||||
|
if (-1 != a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (a.indexOf("foo") !== -1) console.log("PASS");
|
||||||
|
if (-1 !== a.indexOf("foo")) console.log("PASS");
|
||||||
}
|
}
|
||||||
expect: {
|
expect: {
|
||||||
if (~Object.keys({ foo: 42 }).indexOf("foo")) console.log("PASS");
|
var a = Object.keys({ foo: 42 });
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (!~a.indexOf("bar")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
|
if (~a.indexOf("foo")) console.log("PASS");
|
||||||
}
|
}
|
||||||
expect_stdout: "PASS"
|
expect_stdout: [
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
"PASS",
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
issue_3413: {
|
issue_3413: {
|
||||||
|
|||||||
Reference in New Issue
Block a user