diff options
author | Alex Lam S.L <alexlamsl@gmail.com> | 2019-04-25 00:08:08 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-04-25 00:08:08 +0800 |
commit | c2157063505dd211acc907f32a1a7e892aa0973f (patch) | |
tree | 5462f6d0427e5b6776ceee01a701f281775d3c96 | |
parent | d3b93ec682f948e80c9617421128597a12651f78 (diff) | |
download | tracifyjs-c2157063505dd211acc907f32a1a7e892aa0973f.tar.gz tracifyjs-c2157063505dd211acc907f32a1a7e892aa0973f.zip |
enhance `unsafe` `comparisons` (#3381)
-rw-r--r-- | lib/compress.js | 37 | ||||
-rw-r--r-- | test/compress/comparisons.js | 15 |
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" +} |