diff options
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 83 |
1 files changed, 62 insertions, 21 deletions
diff --git a/lib/compress.js b/lib/compress.js index c9892ce2..8bc8b37e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -5916,28 +5916,57 @@ merge(Compressor.prototype, { } body[0].body = decl.concat(body[0].body); self.body = body; - if (body.length == 1 && (body[0] === exact_match || body[0] === default_branch)) { - var has_break = false; - var tw = new TreeWalker(function(node) { - if (has_break - || node instanceof AST_Lambda - || node instanceof AST_SimpleStatement) return true; - if (is_break(node, tw)) has_break = true; + if (compressor.option("conditionals")) switch (body.length) { + case 1: + if (!no_break(self)) break; + var exp = body[0].expression; + var statements = body[0].body.slice(); + if (body[0] !== default_branch && body[0] !== exact_match) return make_node(AST_If, self, { + condition: make_node(AST_Binary, self, { + operator: "===", + left: self.expression, + right: exp, + }), + body: make_node(AST_BlockStatement, self, { + body: statements, + }), + alternative: null, + }).optimize(compressor); + if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, { + body: exp, + })); + statements.unshift(make_node(AST_SimpleStatement, self.expression, { + body:self.expression, + })); + return make_node(AST_BlockStatement, self, { + body: statements, + }).optimize(compressor); + case 2: + if (!member(default_branch, body)) break; + var statements = body[0].body.slice(); + var exclusive = statements.length && is_break(statements[statements.length - 1], compressor); + if (exclusive) statements.pop(); + if (!all(statements, no_break)) break; + var alternative = body[1].body.length && make_node(AST_BlockStatement, body[1], body[1]); + var node = make_node(AST_If, self, { + condition: make_node(AST_Binary, self, body[0] === default_branch ? { + operator: "!==", + left: self.expression, + right: body[1].expression, + } : { + operator: "===", + left: self.expression, + right: body[0].expression, + }), + body: make_node(AST_BlockStatement, body[0], { + body: statements, + }), + alternative: exclusive && alternative || null, }); - self.walk(tw); - if (!has_break) { - var statements = body[0].body.slice(); - var exp = body[0].expression; - if (exp) statements.unshift(make_node(AST_SimpleStatement, exp, { - body: exp - })); - statements.unshift(make_node(AST_SimpleStatement, self.expression, { - body:self.expression - })); - return make_node(AST_BlockStatement, self, { - body: statements - }).optimize(compressor); - } + if (!exclusive && alternative) node = make_node(AST_BlockStatement, self, { + body: [ node, alternative ], + }); + return node.optimize(compressor); } return self; @@ -5945,6 +5974,18 @@ merge(Compressor.prototype, { return node instanceof AST_Break && tw.loopcontrol_target(node) === self; } + function no_break(node) { + var found = false; + var tw = new TreeWalker(function(node) { + if (found + || node instanceof AST_Lambda + || node instanceof AST_SimpleStatement) return true; + if (is_break(node, tw)) found = true; + }); + node.walk(tw); + return !found; + } + function eliminate_branch(branch, prev) { if (prev && !aborts(prev)) { prev.body = prev.body.concat(branch.body); |