From: Alex Lam S.L Date: Tue, 2 Jan 2018 07:09:51 +0000 (+0800) Subject: enhance `if_return` (#2703) X-Git-Url: https://git.ndcode.org/public/gitweb.cgi?a=commitdiff_plain;h=cc931b3ad85ff980e397d598f49fb649d08bc68c;p=UglifyJS.git enhance `if_return` (#2703) --- diff --git a/lib/compress.js b/lib/compress.js index 203c1443..5da07f71 100644 --- a/lib/compress.js +++ b/lib/compress.js @@ -1343,12 +1343,13 @@ merge(Compressor.prototype, { var in_lambda = self instanceof AST_Lambda; for (var i = statements.length; --i >= 0;) { var stat = statements[i]; - var next = statements[i + 1]; + var j = next_index(i); + var next = statements[j]; if (in_lambda && !next && stat instanceof AST_Return) { if (!stat.value) { CHANGED = true; - statements.length--; + statements.splice(i, 1); continue; } if (stat.value instanceof AST_UnaryPrefix && stat.value.operator == "void") { @@ -1418,7 +1419,8 @@ merge(Compressor.prototype, { CHANGED = true; stat = stat.clone(); stat.alternative = next; - statements.splice(i, 2, stat.transform(compressor)); + statements.splice(i, 1, stat.transform(compressor)); + statements.splice(j, 1); continue; } //--- @@ -1430,7 +1432,8 @@ merge(Compressor.prototype, { stat.alternative = next || make_node(AST_Return, stat, { value: null }); - statements.splice(i, next ? 2 : 1, stat.transform(compressor)); + statements.splice(i, 1, stat.transform(compressor)); + if (next) statements.splice(j, 1); continue; } //--- @@ -1439,10 +1442,10 @@ merge(Compressor.prototype, { // if sequences is not enabled, this can lead to an endless loop (issue #866). // however, with sequences on this helps producing slightly better output for // the example code. - var prev = statements[i - 1]; + var prev = statements[prev_index(i)]; if (compressor.option("sequences") && in_lambda && !stat.alternative && prev instanceof AST_If && prev.body instanceof AST_Return - && i + 2 == statements.length && next instanceof AST_SimpleStatement) { + && next_index(j) == statements.length && next instanceof AST_SimpleStatement) { CHANGED = true; stat = stat.clone(); stat.alternative = make_node(AST_BlockStatement, next, { @@ -1453,7 +1456,8 @@ merge(Compressor.prototype, { }) ] }); - statements.splice(i, 2, stat.transform(compressor)); + statements.splice(i, 1, stat.transform(compressor)); + statements.splice(j, 1); continue; } } @@ -1503,6 +1507,26 @@ merge(Compressor.prototype, { } return body; } + + function next_index(i) { + for (var j = i + 1, len = statements.length; j < len; j++) { + var stat = statements[j]; + if (!(stat instanceof AST_Definitions && declarations_only(stat))) { + break; + } + } + return j; + } + + function prev_index(i) { + for (var j = i; --j >= 0;) { + var stat = statements[j]; + if (!(stat instanceof AST_Definitions && declarations_only(stat))) { + break; + } + } + return j; + } } function eliminate_dead_code(statements, compressor) { @@ -1575,19 +1599,17 @@ merge(Compressor.prototype, { 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); + decls.push(line); } else if (stat) { return false; } else { stat = line; } } - [].push.apply(decls, defs); return stat; } @@ -1599,7 +1621,7 @@ merge(Compressor.prototype, { return make_sequence(left, [ left, right ]).transform(compressor); }; var n = 0, prev; - for (var i = 0, len = statements.length; i < len; i++) { + for (var i = 0; i < statements.length; i++) { var stat = statements[i]; if (prev) { if (stat instanceof AST_For && !(stat.init instanceof AST_Definitions)) { @@ -1641,15 +1663,19 @@ merge(Compressor.prototype, { var body = to_simple_statement(stat.body, decls); var alt = to_simple_statement(stat.alternative, decls); if (body !== false && alt !== false && decls.length > 0) { + var len = decls.length; 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 - }); + decls.unshift(n, 1); + [].splice.apply(statements, decls); + i += len; + n += len + 1; + prev = null; CHANGED = true; + continue; } } statements[n++] = stat; diff --git a/test/compress/if_return.js b/test/compress/if_return.js index 72b69e70..a0dfdc9a 100644 --- a/test/compress/if_return.js +++ b/test/compress/if_return.js @@ -326,3 +326,49 @@ issue_512: { } } } + +if_var_return: { + options = { + conditionals: true, + if_return: true, + join_vars: true, + sequences: true, + } + input: { + function f() { + var a; + return; + var b; + } + function g() { + var a; + if (u()) { + var b; + return v(); + var c; + } + var d; + if (w()) { + var e; + return x(); + var f; + } else { + var g; + y(); + var h; + } + var i; + z(); + var j; + } + } + expect: { + function f() { + var a, b; + } + function g() { + var a, b, c, d, e, f, g, h, i, j; + return u() ? v() : w() ? x() : (y(), z(), void 0); + } + } +}