From 581630e0a71cffeadd4887a757889d6a3502275c Mon Sep 17 00:00:00 2001 From: "Alex Lam S.L" Date: Mon, 27 Mar 2017 04:37:42 +0800 Subject: [PATCH] fix typeof side effects (#1696) `statement_to_expression()` drops `typeof` even if it operates on undeclared variables. Since we now have `drop_side_effect_free()`, replace and remove this deprecated functionality. --- lib/compress.js | 31 +++++++++++-------------------- test/compress/negate-iife.js | 9 +++++---- test/compress/switch.js | 14 ++++++++++++++ 3 files changed, 30 insertions(+), 24 deletions(-) diff --git a/lib/compress.js b/lib/compress.js index 9ed368c7..03c8d5dd 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -482,15 +482,6 @@ merge(Compressor.prototype, { return x; }; - var readOnlyPrefix = makePredicate("! ~ + - void typeof"); - function statement_to_expression(stat) { - if (stat.body instanceof AST_UnaryPrefix && readOnlyPrefix(stat.body.operator)) { - return stat.body.expression; - } else { - return stat.body; - } - } - function is_iife_call(node) { if (node instanceof AST_Call && !(node instanceof AST_New)) { return node.expression instanceof AST_Function || is_iife_call(node.expression); @@ -984,10 +975,10 @@ merge(Compressor.prototype, { }; statements.forEach(function(stat){ if (stat instanceof AST_SimpleStatement) { - if (seqLength(seq) >= compressor.sequences_limit) { - push_seq(); - } - seq.push(seq.length > 0 ? statement_to_expression(stat) : stat.body); + if (seqLength(seq) >= compressor.sequences_limit) push_seq(); + var body = stat.body; + if (seq.length > 0) body = body.drop_side_effect_free(compressor); + if (body) seq.push(body); } else { push_seq(); ret.push(stat); @@ -1036,7 +1027,7 @@ merge(Compressor.prototype, { stat.init = cons_seq(stat.init); } else if (!stat.init) { - stat.init = statement_to_expression(prev); + stat.init = prev.body.drop_side_effect_free(compressor); ret.pop(); } } catch(ex) { @@ -2170,6 +2161,7 @@ merge(Compressor.prototype, { switch (this.operator) { case "&&": case "||": + if (right === this.right) return this; var node = this.clone(); node.right = right; return node; @@ -2423,8 +2415,8 @@ merge(Compressor.prototype, { return make_node(AST_SimpleStatement, self, { body: make_node(AST_Conditional, self, { condition : self.condition, - consequent : statement_to_expression(self.body), - alternative : statement_to_expression(self.alternative) + consequent : self.body.body, + alternative : self.alternative.body }) }).optimize(compressor); } @@ -2440,25 +2432,24 @@ merge(Compressor.prototype, { body: make_node(AST_Binary, self, { operator : "||", left : negated, - right : statement_to_expression(self.body) + right : self.body.body }) }).optimize(compressor); return make_node(AST_SimpleStatement, self, { body: make_node(AST_Binary, self, { operator : "&&", left : self.condition, - right : statement_to_expression(self.body) + right : self.body.body }) }).optimize(compressor); } if (self.body instanceof AST_EmptyStatement - && self.alternative && self.alternative instanceof AST_SimpleStatement) { return make_node(AST_SimpleStatement, self, { body: make_node(AST_Binary, self, { operator : "||", left : self.condition, - right : statement_to_expression(self.alternative) + right : self.alternative.body }) }).optimize(compressor); } diff --git a/test/compress/negate-iife.js b/test/compress/negate-iife.js index e9ad37db..343e8e16 100644 --- a/test/compress/negate-iife.js +++ b/test/compress/negate-iife.js @@ -353,8 +353,9 @@ issue_1254_negate_iife_nested: { issue_1288: { options = { - negate_iife: true, conditionals: true, + negate_iife: true, + side_effects: false, }; input: { if (w) ; @@ -374,11 +375,11 @@ issue_1288: { })(0); } expect: { - w || function f() {}(); - x || function() { + w || !function f() {}(); + x || !function() { x = {}; }(); - y ? function() {}() : function(z) { + y ? !function() {}() : !function(z) { return z; }(0); } diff --git a/test/compress/switch.js b/test/compress/switch.js index 654a838b..c3e76302 100644 --- a/test/compress/switch.js +++ b/test/compress/switch.js @@ -579,3 +579,17 @@ issue_1690_2: { } expect_stdout: "PASS" } + +if_switch_typeof: { + options = { + conditionals: true, + dead_code: true, + side_effects: true, + } + input: { + if (a) switch(typeof b) {} + } + expect: { + a; + } +} -- 2.34.1