diff options
Diffstat (limited to 'lib/compress.js')
-rw-r--r-- | lib/compress.js | 90 |
1 files changed, 74 insertions, 16 deletions
diff --git a/lib/compress.js b/lib/compress.js index 56176e55..ee80901e 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -884,6 +884,7 @@ merge(Compressor.prototype, { } if (compressor.sequences_limit > 0) { sequencesize(statements, compressor); + sequencesize_2(statements, compressor); } if (compressor.option("join_vars")) { join_consecutive_vars(statements, compressor); @@ -1537,6 +1538,12 @@ merge(Compressor.prototype, { }); } + function declarations_only(node) { + return all(node.definitions, function(var_def) { + return !var_def.value; + }); + } + function sequencesize(statements, compressor) { if (statements.length < 2) return; var seq = [], n = 0; @@ -1553,6 +1560,9 @@ merge(Compressor.prototype, { var body = stat.body; if (seq.length > 0) body = body.drop_side_effect_free(compressor); if (body) merge_sequence(seq, body); + } else if (stat instanceof AST_Definitions && declarations_only(stat) + || stat instanceof AST_Defun) { + statements[n++] = stat; } else { push_seq(); statements[n++] = stat; @@ -1560,13 +1570,31 @@ merge(Compressor.prototype, { } push_seq(); statements.length = n; - sequencesize_2(statements, compressor); - CHANGED = statements.length != len; + if (n != len) CHANGED = true; + } + + function to_simple_statement(block, decls) { + if (!(block instanceof AST_BlockStatement)) return block; + var defs = []; + var stat = null; + for (var i = 0, len = block.body.length; i < len; i++) { + var line = block.body[i]; + if (line instanceof AST_Definitions && declarations_only(line)) { + defs.push(line); + } else if (stat) { + return false; + } else { + stat = line; + } + } + [].push.apply(decls, defs); + return stat; } function sequencesize_2(statements, compressor) { function cons_seq(right) { n--; + CHANGED = true; var left = prev.body; return make_sequence(left, [ left, right ]).transform(compressor); }; @@ -1588,6 +1616,7 @@ merge(Compressor.prototype, { else { stat.init = prev.body; n--; + CHANGED = true; } } } @@ -1607,6 +1636,22 @@ merge(Compressor.prototype, { stat.expression = cons_seq(stat.expression); } } + if (compressor.option("conditionals") && stat instanceof AST_If) { + var decls = []; + var body = to_simple_statement(stat.body, decls); + var alt = to_simple_statement(stat.alternative, decls); + if (body !== false && alt !== false && decls.length > 0) { + decls.push(make_node(AST_If, stat, { + condition: stat.condition, + body: body || make_node(AST_EmptyStatement, stat.body), + alternative: alt + })); + stat = make_node(AST_BlockStatement, stat, { + body: decls + }); + CHANGED = true; + } + } statements[n++] = stat; prev = stat instanceof AST_SimpleStatement ? stat : null; } @@ -1614,30 +1659,43 @@ merge(Compressor.prototype, { } function join_consecutive_vars(statements, compressor) { + var defs; for (var i = 0, j = -1, len = statements.length; i < len; i++) { var stat = statements[i]; var prev = statements[j]; - if (stat instanceof AST_Definitions && prev && prev.TYPE == stat.TYPE) { - prev.definitions = prev.definitions.concat(stat.definitions); - CHANGED = true; - } - else if (stat instanceof AST_For - && prev instanceof AST_Var - && (!stat.init || stat.init.TYPE == prev.TYPE)) { - CHANGED = true; - if (stat.init) { - stat.init.definitions = prev.definitions.concat(stat.init.definitions); + if (stat instanceof AST_Definitions) { + if (prev && prev.TYPE == stat.TYPE) { + prev.definitions = prev.definitions.concat(stat.definitions); + CHANGED = true; + } else if (defs && defs.TYPE == stat.TYPE && declarations_only(stat)) { + defs.definitions = defs.definitions.concat(stat.definitions); + CHANGED = true; } else { + statements[++j] = stat; + defs = stat; + } + } else if (stat instanceof AST_For) { + if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) { + if (stat.init) { + prev.definitions = prev.definitions.concat(stat.init.definitions); + } stat.init = prev; + statements[j] = stat; + CHANGED = true; + } else if (defs && stat.init && defs.TYPE == stat.init.TYPE && declarations_only(stat.init)) { + defs.definitions = defs.definitions.concat(stat.init.definitions); + stat.init = null; + statements[++j] = stat; + CHANGED = true; + } else { + statements[++j] = stat; } - statements[j] = stat; - } - else { + } else { statements[++j] = stat; } } statements.length = j + 1; - }; + } } function extract_declarations_from_unreachable_code(compressor, stat, target) { |