enhance unsafe comparisons (#3381)

This commit is contained in:
Alex Lam S.L
2019-04-25 00:08:08 +08:00
committed by GitHub
parent d3b93ec682
commit c215706350
2 changed files with 52 additions and 0 deletions

View File

@@ -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) {

View File

@@ -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"
}