diff --git a/lib/compress.js b/lib/compress.js index b48d7bcf13..46b59b9259 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -8792,17 +8792,58 @@ Compressor.prototype.compress = function(node) { self.body = self.alternative || make_node(AST_EmptyStatement, self); self.alternative = tmp; } - var body = [], var_defs = [], refs = []; - var body_exprs = sequencesize(self.body, body, var_defs, refs); - var alt_exprs = sequencesize(self.alternative, body, var_defs, refs); + var body_defuns = []; + var body_var_defs = []; + var body_refs = []; + var body_exprs = sequencesize(self.body, body_defuns, body_var_defs, body_refs); + var alt_defuns = []; + var alt_var_defs = []; + var alt_refs = []; + var alt_exprs = sequencesize(self.alternative, alt_defuns, alt_var_defs, alt_refs); if (body_exprs instanceof AST_BlockStatement || alt_exprs instanceof AST_BlockStatement) { + var body = [], var_defs = []; + if (body_exprs) { + [].push.apply(body, body_defuns); + [].push.apply(var_defs, body_var_defs); + if (body_exprs instanceof AST_BlockStatement) { + self.body = body_exprs; + } else if (body_exprs.length == 0) { + self.body = make_node(AST_EmptyStatement, self.body); + } else { + self.body = make_node(AST_SimpleStatement, self.body, { + body: make_sequence(self.body, body_exprs), + }); + } + body_refs.forEach(function(ref) { + ref.definition().references.push(ref); + }); + } + if (alt_exprs) { + [].push.apply(body, alt_defuns); + [].push.apply(var_defs, alt_var_defs); + if (alt_exprs instanceof AST_BlockStatement) { + self.alternative = alt_exprs; + } else if (alt_exprs.length == 0) { + self.alternative = null; + } else { + self.alternative = make_node(AST_SimpleStatement, self.alternative, { + body: make_sequence(self.alternative, alt_exprs), + }); + } + alt_refs.forEach(function(ref) { + ref.definition().references.push(ref); + }); + } if (var_defs.length > 0) body.push(make_node(AST_Var, self, { definitions: var_defs })); - body.push(self); - if (body_exprs instanceof AST_BlockStatement) self.body = body_exprs; - if (alt_exprs instanceof AST_BlockStatement) self.alternative = alt_exprs; - return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + if (body.length > 0) { + body.push(self); + return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); + } } else if (body_exprs && alt_exprs) { - if (var_defs.length > 0) body.push(make_node(AST_Var, self, { definitions: var_defs })); + var body = body_defuns.concat(alt_defuns); + if (body_var_defs.length > 0 || alt_var_defs.length > 0) body.push(make_node(AST_Var, self, { + definitions: body_var_defs.concat(alt_var_defs), + })); if (body_exprs.length == 0) { body.push(make_node(AST_SimpleStatement, self.condition, { body: alt_exprs.length > 0 ? make_node(AST_Binary, self, { @@ -8835,7 +8876,10 @@ Compressor.prototype.compress = function(node) { }), }).optimize(compressor)); } - refs.forEach(function(ref) { + body_refs.forEach(function(ref) { + ref.definition().references.push(ref); + }); + alt_refs.forEach(function(ref) { ref.definition().references.push(ref); }); return make_node(AST_BlockStatement, self, { body: body }).optimize(compressor); diff --git a/test/compress/conditionals.js b/test/compress/conditionals.js index 84559c327c..a7a96078f5 100644 --- a/test/compress/conditionals.js +++ b/test/compress/conditionals.js @@ -1924,3 +1924,86 @@ object_super: { expect_stdout: "PASS" node_version: ">=4" } + +issue_5232_1: { + options = { + conditionals: true, + } + input: { + (function() { + if (Math) { + function f() {} + for (var a in [ 42 ]) + console.log(typeof f); + } else { + var b = null; + return true; + } + })(); + } + expect: { + (function() { + var b; + if (!Math) + return b = null, true; + function f() {} + for (var a in [ 42 ]) console.log(typeof f); + })(); + } + expect_stdout: "function" +} + +issue_5232_2: { + options = { + conditionals: true, + } + input: { + console.log(function() { + if (!Math); + else { + var b = null; + return "PASS"; + } + }()); + } + expect: { + console.log(function() { + var b; + if (Math) + return b = null, "PASS"; + }()); + } + expect_stdout: "PASS" +} + +issue_5232_3: { + options = { + conditionals: true, + } + input: { + console.log(function() { + return function() { + if (console) + console.log("PASS"); + else { + var a = null; + return "FAIL"; + } + }; + }()()); + } + expect: { + console.log(function() { + return function() { + var a; + if (!console) + return a = null, "FAIL"; + console.log("PASS"); + }; + }()()); + } + expect_stdout: [ + "PASS", + "undefined", + ] +} diff --git a/test/reduce.js b/test/reduce.js index 30272de0bb..28d06c465e 100644 --- a/test/reduce.js +++ b/test/reduce.js @@ -548,7 +548,7 @@ module.exports = function reduce_test(testcase, minify_options, reduce_options) })); var before_iterations = testcase; for (var c = 0; c < max_iterations; ++c) { - if (verbose && pass == 1 && c % 25 == 0) { + if (verbose && c % (pass == 1 ? 25 : 100) == 0) { log("// reduce test pass " + pass + ", iteration " + c + ": " + testcase.length + " bytes"); } var CHANGED = false;