From fedb6191a11c2d868c23362e10f23795aae3ca3e Mon Sep 17 00:00:00 2001 From: kzc Date: Thu, 11 Jun 2015 23:22:38 -0400 Subject: [PATCH] optimizations for && and || where left side is constant expression --- lib/compress.js | 28 ++++++ test/compress/conditionals.js | 161 ++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) diff --git a/lib/compress.js b/lib/compress.js index 530e7c2f..34233143 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2104,6 +2104,34 @@ merge(Compressor.prototype, { } break; } + if (compressor.option("conditionals")) { + if (self.operator == "&&") { + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if (ll.length > 1) { + if (ll[1]) { + compressor.warn("Condition left of && always true [{file}:{line},{col}]", self.start); + return rr[0]; + } else { + compressor.warn("Condition left of && always false [{file}:{line},{col}]", self.start); + return ll[0]; + } + } + } + if (self.operator == "||") { + var ll = self.left.evaluate(compressor); + var rr = self.right.evaluate(compressor); + if (ll.length > 1) { + if (ll[1]) { + compressor.warn("Condition left of || always true [{file}:{line},{col}]", self.start); + return ll[0]; + } else { + compressor.warn("Condition left of || always false [{file}:{line},{col}]", self.start); + return rr[0]; + } + } + } + } if (compressor.option("booleans") && compressor.in_boolean_context()) switch (self.operator) { case "&&": var ll = self.left.evaluate(compressor); diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js index 1b961812..78f087db 100644 --- a/test/compress/conditionals.js +++ b/test/compress/conditionals.js @@ -384,3 +384,164 @@ cond_8: { a = condition ? 1 : 0; } } + +conditional_and: { + options = { + conditionals: true, + evaluate : true + }; + input: { + var a; + // compress these + + a = true && condition; + a = 1 && console.log("a"); + a = 2 * 3 && 2 * condition; + a = 5 == 5 && condition + 3; + a = "string" && 4 - condition; + a = 5 + "" && condition / 5; + a = -4.5 && 6 << condition; + a = 6 && 7; + + a = false && condition; + a = NaN && console.log("b"); + a = 0 && console.log("c"); + a = undefined && 2 * condition; + a = null && condition + 3; + a = 2 * 3 - 6 && 4 - condition; + a = 10 == 7 && condition / 5; + a = !"string" && 6 % condition; + a = 0 && 7; + + // don't compress these + + a = condition && true; + a = console.log("a") && 2; + a = 4 - condition && "string"; + a = 6 << condition && -4.5; + + a = condition && false; + a = console.log("b") && NaN; + a = console.log("c") && 0; + a = 2 * condition && undefined; + a = condition + 3 && null; + + } + expect: { + var a; + + a = condition; + a = console.log("a"); + a = 2 * condition; + a = condition + 3; + a = 4 - condition; + a = condition / 5; + a = 6 << condition; + a = 7; + + a = false; + a = NaN; + a = 0; + a = void 0; + a = null; + a = 0; + a = false; + a = false; + a = 0; + + a = condition && true; + a = console.log("a") && 2; + a = 4 - condition && "string"; + a = 6 << condition && -4.5; + + a = condition && false; + a = console.log("b") && NaN; + a = console.log("c") && 0; + a = 2 * condition && void 0; + a = condition + 3 && null; + } +} + +conditional_or: { + options = { + conditionals: true, + evaluate : true + }; + input: { + var a; + // compress these + + a = true || condition; + a = 1 || console.log("a"); + a = 2 * 3 || 2 * condition; + a = 5 == 5 || condition + 3; + a = "string" || 4 - condition; + a = 5 + "" || condition / 5; + a = -4.5 || 6 << condition; + a = 6 || 7; + + a = false || condition; + a = 0 || console.log("b"); + a = NaN || console.log("c"); + a = undefined || 2 * condition; + a = null || condition + 3; + a = 2 * 3 - 6 || 4 - condition; + a = 10 == 7 || condition / 5; + a = !"string" || 6 % condition; + a = null || 7; + + a = console.log(undefined && condition || null); + a = console.log(undefined || condition && null); + + // don't compress these + + a = condition || true; + a = console.log("a") || 2; + a = 4 - condition || "string"; + a = 6 << condition || -4.5; + + a = condition || false; + a = console.log("b") || NaN; + a = console.log("c") || 0; + a = 2 * condition || undefined; + a = condition + 3 || null; + + } + expect: { + var a; + + a = true; + a = 1; + a = 6; + a = true; + a = "string"; + a = "5"; + a = -4.5; + a = 6; + + a = condition; + a = console.log("b"); + a = console.log("c"); + a = 2 * condition; + a = condition + 3; + a = 4 - condition; + a = condition / 5; + a = 6 % condition; + a = 7; + + a = console.log(null); + a = console.log(condition && null); + + a = condition || true; + a = console.log("a") || 2; + a = 4 - condition || "string"; + a = 6 << condition || -4.5; + + a = condition || false; + a = console.log("b") || NaN; + a = console.log("c") || 0; + a = 2 * condition || void 0; + a = condition + 3 || null; + } +} + -- 2.34.1