diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/compress.js | 120 |
1 files changed, 61 insertions, 59 deletions
diff --git a/lib/compress.js b/lib/compress.js index 6359696b..374d14d4 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -924,6 +924,45 @@ merge(Compressor.prototype, { // step. nevertheless, it's good to check. continue loop; case stat instanceof AST_If: + var ab = aborts(stat.body); + if (can_merge_flow(ab)) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + var funs = extract_functions_from_statement_array(ret); + var body = as_statement_array_with_return(stat.body, ab); + stat = stat.clone(); + stat.condition = stat.condition.negate(compressor); + stat.body = make_node(AST_BlockStatement, stat, { + body: as_statement_array(stat.alternative).concat(ret) + }); + stat.alternative = make_node(AST_BlockStatement, stat, { + body: body + }); + ret = [ stat.transform(compressor) ].concat(funs); + continue loop; + } + + var ab = aborts(stat.alternative); + if (can_merge_flow(ab)) { + if (ab.label) { + remove(ab.label.thedef.references, ab); + } + CHANGED = true; + var funs = extract_functions_from_statement_array(ret); + stat = stat.clone(); + stat.body = make_node(AST_BlockStatement, stat.body, { + body: as_statement_array(stat.body).concat(ret) + }); + var body = as_statement_array_with_return(stat.alternative, ab); + stat.alternative = make_node(AST_BlockStatement, stat.alternative, { + body: body + }); + ret = [ stat.transform(compressor) ].concat(funs); + continue loop; + } + if (stat.body instanceof AST_Return) { var value = stat.body.value; //--- @@ -960,23 +999,6 @@ merge(Compressor.prototype, { continue loop; } //--- - // if (foo()) return [ void bar() ]; [ else x...; ] y... ==> if (!foo()) { x...; y... } else bar(); - if (in_lambda && (!value || value instanceof AST_UnaryPrefix && value.operator == "void")) { - CHANGED = true; - stat = stat.clone(); - stat.condition = stat.condition.negate(compressor); - var funs = extract_functions_from_statement_array(ret); - var body = as_statement_array(stat.alternative).concat(ret); - stat.body = make_node(AST_BlockStatement, stat, { - body: body - }); - stat.alternative = value ? make_node(AST_SimpleStatement, value, { - body: value.expression - }) : null; - ret = [ stat.transform(compressor) ].concat(funs); - continue loop; - } - //--- // if (a) return b; if (c) return d; e; ==> return a ? b : c ? d : void e; // // if sequences is not enabled, this can lead to an endless loop (issue #866). @@ -995,48 +1017,6 @@ merge(Compressor.prototype, { } } - var ab = aborts(stat.body); - var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; - if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda) - || (ab instanceof AST_Continue && self === loop_body(lct)) - || (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) { - if (ab.label) { - remove(ab.label.thedef.references, ab); - } - CHANGED = true; - var body = as_statement_array(stat.body).slice(0, -1); - stat = stat.clone(); - stat.condition = stat.condition.negate(compressor); - stat.body = make_node(AST_BlockStatement, stat, { - body: as_statement_array(stat.alternative).concat(ret) - }); - stat.alternative = make_node(AST_BlockStatement, stat, { - body: body - }); - ret = [ stat.transform(compressor) ]; - continue loop; - } - - var ab = aborts(stat.alternative); - var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; - if (ab && ((ab instanceof AST_Return && !ab.value && in_lambda) - || (ab instanceof AST_Continue && self === loop_body(lct)) - || (ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct))) { - if (ab.label) { - remove(ab.label.thedef.references, ab); - } - CHANGED = true; - stat = stat.clone(); - stat.body = make_node(AST_BlockStatement, stat.body, { - body: as_statement_array(stat.body).concat(ret) - }); - stat.alternative = make_node(AST_BlockStatement, stat.alternative, { - body: as_statement_array(stat.alternative).slice(0, -1) - }); - ret = [ stat.transform(compressor) ]; - continue loop; - } - ret.unshift(stat); break; default: @@ -1056,6 +1036,28 @@ merge(Compressor.prototype, { } return false; } + + function is_return_void(value) { + return !value || value instanceof AST_UnaryPrefix && value.operator == "void"; + } + + function can_merge_flow(ab) { + if (!ab) return false; + var lct = ab instanceof AST_LoopControl ? compressor.loopcontrol_target(ab) : null; + return ab instanceof AST_Return && in_lambda && is_return_void(ab.value) + || ab instanceof AST_Continue && self === loop_body(lct) + || ab instanceof AST_Break && lct instanceof AST_BlockStatement && self === lct; + } + + function as_statement_array_with_return(node, ab) { + var body = as_statement_array(node).slice(0, -1); + if (ab.value) { + body.push(make_node(AST_SimpleStatement, ab.value, { + body: ab.value.expression + })); + } + return body; + } }; function eliminate_dead_code(statements, compressor) { |