enhance unsafe comparisons (#3381)
This commit is contained in:
@@ -5495,6 +5495,7 @@ merge(Compressor.prototype, {
|
|||||||
return this;
|
return this;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
var indexFns = makePredicate("indexOf lastIndexOf");
|
||||||
var commutativeOperators = makePredicate("== === != !== * & | ^");
|
var commutativeOperators = makePredicate("== === != !== * & | ^");
|
||||||
function is_object(node) {
|
function is_object(node) {
|
||||||
return node instanceof AST_Array
|
return node instanceof AST_Array
|
||||||
@@ -5913,6 +5914,25 @@ merge(Compressor.prototype, {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (compressor.option("unsafe")
|
||||||
|
&& self.right instanceof AST_Call
|
||||||
|
&& self.right.expression instanceof AST_Dot
|
||||||
|
&& indexFns[self.right.expression.property]) {
|
||||||
|
if (compressor.option("comparisons") && is_indexOf_match_pattern()) {
|
||||||
|
var node = make_node(AST_UnaryPrefix, self, {
|
||||||
|
operator: "!",
|
||||||
|
expression: make_node(AST_UnaryPrefix, self, {
|
||||||
|
operator: "~",
|
||||||
|
expression: self.right
|
||||||
|
})
|
||||||
|
});
|
||||||
|
if (self.operator == "!=" || self.operator == "<=") node = make_node(AST_UnaryPrefix, self, {
|
||||||
|
operator: "!",
|
||||||
|
expression: node
|
||||||
|
});
|
||||||
|
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
|
||||||
@@ -5946,6 +5966,23 @@ merge(Compressor.prototype, {
|
|||||||
if (node.is_truthy()) return true;
|
if (node.is_truthy()) return true;
|
||||||
return node.evaluate(compressor);
|
return node.evaluate(compressor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function is_indexOf_match_pattern() {
|
||||||
|
switch (self.operator) {
|
||||||
|
case ">":
|
||||||
|
case "<=":
|
||||||
|
// 0 > array.indexOf(string) => !~array.indexOf(string)
|
||||||
|
// 0 <= array.indexOf(string) => !!~array.indexOf(string)
|
||||||
|
return self.left instanceof AST_Number && self.left.getValue() == 0;
|
||||||
|
case "==":
|
||||||
|
case "!=":
|
||||||
|
// -1 == array.indexOf(string) => !~array.indexOf(string)
|
||||||
|
// -1 != array.indexOf(string) => !!~array.indexOf(string)
|
||||||
|
return self.left instanceof AST_Number && self.left.getValue() == -1
|
||||||
|
|| self.left instanceof AST_UnaryPrefix && self.left.operator == "-"
|
||||||
|
&& self.left.expression instanceof AST_Number && self.left.expression.getValue() == 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function recursive_ref(compressor, def) {
|
function recursive_ref(compressor, def) {
|
||||||
|
|||||||
@@ -365,3 +365,18 @@ is_defined: {
|
|||||||
"WARN: Expression always defined [test/compress/comparisons.js:2,19]",
|
"WARN: Expression always defined [test/compress/comparisons.js:2,19]",
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsafe_indexOf: {
|
||||||
|
options = {
|
||||||
|
booleans: true,
|
||||||
|
comparisons: true,
|
||||||
|
unsafe: true,
|
||||||
|
}
|
||||||
|
input: {
|
||||||
|
if (Object.keys({ foo: 42 }).indexOf("foo") >= 0) console.log("PASS");
|
||||||
|
}
|
||||||
|
expect: {
|
||||||
|
if (~Object.keys({ foo: 42 }).indexOf("foo")) console.log("PASS");
|
||||||
|
}
|
||||||
|
expect_stdout: "PASS"
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user