aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-04-25 00:08:08 +0800
committerGitHub <noreply@github.com>2019-04-25 00:08:08 +0800
commitc2157063505dd211acc907f32a1a7e892aa0973f (patch)
tree5462f6d0427e5b6776ceee01a701f281775d3c96
parentd3b93ec682f948e80c9617421128597a12651f78 (diff)
downloadtracifyjs-c2157063505dd211acc907f32a1a7e892aa0973f.tar.gz
tracifyjs-c2157063505dd211acc907f32a1a7e892aa0973f.zip
enhance `unsafe` `comparisons` (#3381)
-rw-r--r--lib/compress.js37
-rw-r--r--test/compress/comparisons.js15
2 files changed, 52 insertions, 0 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 758e4595..71081350 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -5495,6 +5495,7 @@ merge(Compressor.prototype, {
return this;
});
+ var indexFns = makePredicate("indexOf lastIndexOf");
var commutativeOperators = makePredicate("== === != !== * & | ^");
function is_object(node) {
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
@@ -5946,6 +5966,23 @@ merge(Compressor.prototype, {
if (node.is_truthy()) return true;
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) {
diff --git a/test/compress/comparisons.js b/test/compress/comparisons.js
index 46805625..ef0db00c 100644
--- a/test/compress/comparisons.js
+++ b/test/compress/comparisons.js
@@ -365,3 +365,18 @@ is_defined: {
"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"
+}