From 99ac73a635d641935331e71d519c24297b50dd32 Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Tue, 31 Dec 2019 13:10:05 +0800 Subject: [PATCH] enhance `booleans` (#3661) --- lib/ast.js | 5 +++-- lib/compress.js | 29 +++++++++++++++++------------ test/compress/collapse_vars.js | 4 ++-- test/compress/transform.js | 1 + 4 files changed, 23 insertions(+), 16 deletions(-) diff --git a/lib/ast.js b/lib/ast.js index 11d1f361..f2052350 100644 --- a/lib/ast.js +++ b/lib/ast.js @@ -964,12 +964,13 @@ TreeWalker.prototype = { in_boolean_context: function() { var self = this.self(); for (var i = 0, p; p = this.parent(i); i++) { - if (p instanceof AST_SimpleStatement - || p instanceof AST_Conditional && p.condition === self + if (p instanceof AST_Conditional && p.condition === self || p instanceof AST_DWLoop && p.condition === self || p instanceof AST_For && p.condition === self || p instanceof AST_If && p.condition === self || p instanceof AST_Return && p.in_bool + || p instanceof AST_Sequence && p.tail_node() !== self + || p instanceof AST_SimpleStatement || p instanceof AST_UnaryPrefix && p.operator == "!" && p.expression === self) { return true; } diff --git a/lib/compress.js b/lib/compress.js index 3f6bc893..38d09068 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -2021,6 +2021,7 @@ merge(Compressor.prototype, { if (stat instanceof AST_If && stat.body instanceof AST_Return) { var value = stat.body.value; + var in_bool = stat.body.in_bool || next instanceof AST_Return && next.in_bool; //--- // pretty silly case, but: // if (foo()) return; return; => foo(); return; @@ -2034,7 +2035,7 @@ merge(Compressor.prototype, { } //--- // if (foo()) return x; return y; => return foo() ? x : y; - if (value && !stat.alternative && next instanceof AST_Return && next.value) { + if ((in_bool || value) && !stat.alternative && next instanceof AST_Return) { CHANGED = true; stat = stat.clone(); stat.alternative = next; @@ -2044,16 +2045,13 @@ merge(Compressor.prototype, { } //--- // if (foo()) return x; [ return ; ] => return foo() ? x : undefined; - if (value && !stat.alternative - && (!next && in_lambda && multiple_if_returns - || next instanceof AST_Return)) { + if (!stat.alternative && !next && in_lambda && (in_bool || value && multiple_if_returns)) { CHANGED = true; stat = stat.clone(); - stat.alternative = next || make_node(AST_Return, stat, { + stat.alternative = make_node(AST_Return, stat, { value: null }); statements.splice(i, 1, stat.transform(compressor)); - if (next) statements.splice(j, 1); continue; } //--- @@ -5104,13 +5102,17 @@ merge(Compressor.prototype, { if (self.body instanceof AST_Exit && self.alternative instanceof AST_Exit && self.body.TYPE == self.alternative.TYPE) { - return make_node(self.body.CTOR, self, { + var exit = make_node(self.body.CTOR, self, { value: make_node(AST_Conditional, self, { condition : self.condition, consequent : self.body.value || make_node(AST_Undefined, self.body), alternative : self.alternative.value || make_node(AST_Undefined, self.alternative) - }).transform(compressor) - }).optimize(compressor); + }) + }); + if (exit instanceof AST_Return) { + exit.in_bool = self.body.in_bool || self.alternative.in_bool; + } + return exit; } if (self.body instanceof AST_If && !self.body.alternative @@ -7321,12 +7323,15 @@ merge(Compressor.prototype, { && node.expression instanceof AST_Constant && !node.expression.value); } - // AST_False or !1 + // AST_False or !1 or void 0 function is_false(node) { return node instanceof AST_False || in_bool - && node instanceof AST_Constant - && !node.value + && (node instanceof AST_Constant + && !node.value + || node instanceof AST_UnaryPrefix + && node.operator == "void" + && !node.expression.has_side_effects(compressor)) || (node instanceof AST_UnaryPrefix && node.operator == "!" && node.expression instanceof AST_Constant diff --git a/test/compress/collapse_vars.js b/test/compress/collapse_vars.js index 796fdb3f..a5975279 100644 --- a/test/compress/collapse_vars.js +++ b/test/compress/collapse_vars.js @@ -5863,8 +5863,8 @@ issue_2974: { var c = 0; (function(b) { var a = 2; - for (; b.null = -4, c++, b.null && --a > 0;); - })(!0), + for (;c++, (!0).null && --a > 0;); + })(), console.log(c); } expect_stdout: "1" diff --git a/test/compress/transform.js b/test/compress/transform.js index 867b8ade..66f19bd1 100644 --- a/test/compress/transform.js +++ b/test/compress/transform.js @@ -103,6 +103,7 @@ if_return: { booleans: true, conditionals: true, if_return: true, + passes: 2, sequences: true, side_effects: true, } -- 2.34.1