aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2019-05-17 01:28:18 +0800
committerGitHub <noreply@github.com>2019-05-17 01:28:18 +0800
commita246195412e2864993f00e32aade193234d0aa68 (patch)
tree59dc88b25ec09429238529c5e69ab7ddd2ff4fd7
parent8939a36bc73953920b175da51d65a27f016a5538 (diff)
downloadtracifyjs-a246195412e2864993f00e32aade193234d0aa68.tar.gz
tracifyjs-a246195412e2864993f00e32aade193234d0aa68.zip
enhance `unsafe` `comparisons` (#3419)
-rw-r--r--lib/compress.js40
-rw-r--r--test/compress/comparisons.js51
2 files changed, 75 insertions, 16 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 5d6567f7..b7e5b3d2 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -5969,11 +5969,10 @@ 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("unsafe")) {
+ var indexRight = is_indexFn(self.right);
if (compressor.option("booleans")
+ && indexRight
&& (self.operator == "==" || self.operator == "!=")
&& self.left instanceof AST_Number
&& self.left.getValue() == 0
@@ -5983,18 +5982,26 @@ merge(Compressor.prototype, {
expression: self.right
}) : self.right).optimize(compressor);
}
+ var indexLeft = is_indexFn(self.left);
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
+ expression: indexLeft ? self.left : self.right
})
});
- if (self.operator == "!=" || self.operator == "<=") node = make_node(AST_UnaryPrefix, self, {
- operator: "!",
- expression: node
- });
+ switch (self.operator) {
+ case "<":
+ if (indexLeft) break;
+ case "<=":
+ case "!=":
+ node = make_node(AST_UnaryPrefix, self, {
+ operator: "!",
+ expression: node
+ });
+ break;
+ }
return node.optimize(compressor);
}
}
@@ -6032,17 +6039,26 @@ merge(Compressor.prototype, {
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() {
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;
+ 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 "!=":
// -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
|| self.left instanceof AST_UnaryPrefix && self.left.operator == "-"
&& self.left.expression instanceof AST_Number && self.left.expression.getValue() == 1;
diff --git a/test/compress/comparisons.js b/test/compress/comparisons.js
index 461f415c..bb140fd8 100644
--- a/test/compress/comparisons.js
+++ b/test/compress/comparisons.js
@@ -373,12 +373,55 @@ unsafe_indexOf: {
unsafe: true,
}
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: {
- if (~Object.keys({ foo: 42 }).indexOf("foo")) console.log("PASS");
- }
- expect_stdout: "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",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ "PASS",
+ ]
}
issue_3413: {