diff --git a/lib/compress.js b/lib/compress.js index 011bb1b4..f52bde68 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -3417,23 +3417,27 @@ merge(Compressor.prototype, { }); function if_break_in_loop(self, compressor) { - function drop_it(rest) { - rest = as_statement_array(rest); - if (self.body instanceof AST_BlockStatement) { - self.body = self.body.clone(); - self.body.body = rest.concat(self.body.body.slice(1)); - self.body = self.body.transform(compressor); - } else { - self.body = make_node(AST_BlockStatement, self.body, { - body: rest - }).transform(compressor); - } - if_break_in_loop(self, compressor); - } var first = self.body instanceof AST_BlockStatement ? self.body.body[0] : self.body; + if (is_break(first)) { + var body = []; + if (self.init instanceof AST_Statement) { + body.push(self.init); + } else if (self.init) { + body.push(make_node(AST_SimpleStatement, self.init, { + body: self.init + })); + } + if (self.condition) { + body.push(make_node(AST_SimpleStatement, self.condition, { + body: self.condition + })); + } + return make_node(AST_BlockStatement, self, { + body: body + }); + } if (first instanceof AST_If) { - if (first.body instanceof AST_Break - && compressor.loopcontrol_target(first.body) === compressor.self()) { + if (is_break(first.body)) { if (self.condition) { self.condition = make_node(AST_Binary, self.condition, { left: self.condition, @@ -3444,9 +3448,7 @@ merge(Compressor.prototype, { self.condition = first.condition.negate(compressor); } drop_it(first.alternative); - } - else if (first.alternative instanceof AST_Break - && compressor.loopcontrol_target(first.alternative) === compressor.self()) { + } else if (is_break(first.alternative)) { if (self.condition) { self.condition = make_node(AST_Binary, self.condition, { left: self.condition, @@ -3459,6 +3461,26 @@ merge(Compressor.prototype, { drop_it(first.body); } } + return self; + + function is_break(node) { + return node instanceof AST_Break + && compressor.loopcontrol_target(node) === compressor.self(); + } + + function drop_it(rest) { + rest = as_statement_array(rest); + if (self.body instanceof AST_BlockStatement) { + self.body = self.body.clone(); + self.body.body = rest.concat(self.body.body.slice(1)); + self.body = self.body.transform(compressor); + } else { + self.body = make_node(AST_BlockStatement, self.body, { + body: rest + }).transform(compressor); + } + self = if_break_in_loop(self, compressor); + } }; OPT(AST_For, function(self, compressor){ @@ -3495,8 +3517,7 @@ merge(Compressor.prototype, { } } } - if_break_in_loop(self, compressor); - return self; + return if_break_in_loop(self, compressor); }); OPT(AST_If, function(self, compressor){ diff --git a/test/compress/loops.js b/test/compress/loops.js index 3538c221..8e677ac1 100644 --- a/test/compress/loops.js +++ b/test/compress/loops.js @@ -492,3 +492,44 @@ dead_code_condition: { } expect_stdout: "1" } + +issue_2740_1: { + options = { + loops: true, + } + input: { + for (; ; ) break; + for (a(); ; ) break; + for (; b(); ) break; + for (c(); d(); ) break; + for (; ; e()) break; + for (f(); ; g()) break; + for (; h(); i()) break; + for (j(); k(); l()) break; + } + expect: { + a(); + b(); + c(); + d(); + f(); + h(); + j(); + k(); + } +} + +issue_2740_2: { + options = { + loops: true, + passes: 2, + } + input: { + L1: while (x()) { + break L1; + } + } + expect: { + x(); + } +}