aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2018-01-02 15:09:51 +0800
committerGitHub <noreply@github.com>2018-01-02 15:09:51 +0800
commitcc931b3ad85ff980e397d598f49fb649d08bc68c (patch)
tree257ee5ef6c34e6472c1174dbd3b74d89c91d5552
parentd838b4b52e4b7bea5e2f473469c07f6a3cce397d (diff)
downloadtracifyjs-cc931b3ad85ff980e397d598f49fb649d08bc68c.tar.gz
tracifyjs-cc931b3ad85ff980e397d598f49fb649d08bc68c.zip
enhance `if_return` (#2703)
-rw-r--r--lib/compress.js54
-rw-r--r--test/compress/if_return.js46
2 files changed, 86 insertions, 14 deletions
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);
+ }
+ }
+}