diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 49 |
1 files changed, 48 insertions, 1 deletions
diff --git a/lib/compress.js b/lib/compress.js index 59c9128d..1571173c 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1118,11 +1118,57 @@ merge(Compressor.prototype, { return self; }); + 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 (first instanceof AST_If) { + if (first.body instanceof AST_Break + && compressor.loopcontrol_target(first.body.label) === self) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition.negate(compressor), + }); + } else { + self.condition = first.condition.negate(compressor); + } + drop_it(first.alternative); + } + else if (first.alternative instanceof AST_Break + && compressor.loopcontrol_target(first.alternative.label) === self) { + if (self.condition) { + self.condition = make_node(AST_Binary, self.condition, { + left: self.condition, + operator: "&&", + right: first.condition, + }); + } else { + self.condition = first.condition; + } + drop_it(first.body); + } + } + }; + OPT(AST_While, function(self, compressor) { if (!compressor.option("loops")) return self; self = AST_DWLoop.prototype.optimize.call(self, compressor); if (self instanceof AST_While) { - self = make_node(AST_For, self, self); + if_break_in_loop(self, compressor); + self = make_node(AST_For, self, self).transform(compressor); } return self; }); @@ -1151,6 +1197,7 @@ merge(Compressor.prototype, { } } } + if_break_in_loop(self, compressor); return self; }); |