aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-09-10 15:31:34 +0100
committerGitHub <noreply@github.com>2020-09-10 22:31:34 +0800
commitd7456a2dc220112a5fc294b102612c568395d72c (patch)
treed038a47ec99397258ca23c73612b75e7e79d2c43
parentd97672613d28632a038fa14eb35d8c19c748320d (diff)
downloadtracifyjs-d7456a2dc220112a5fc294b102612c568395d72c.tar.gz
tracifyjs-d7456a2dc220112a5fc294b102612c568395d72c.zip
enhance `if_return` (#4097)
-rw-r--r--lib/compress.js69
-rw-r--r--test/compress/if_return.js69
2 files changed, 114 insertions, 24 deletions
diff --git a/lib/compress.js b/lib/compress.js
index f744ac6a..50a37a68 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -2113,18 +2113,22 @@ merge(Compressor.prototype, {
eliminate_spurious_blocks(stat.body);
[].splice.apply(statements, [i, 1].concat(stat.body));
i += stat.body.length;
- } else if (stat instanceof AST_EmptyStatement) {
- CHANGED = true;
- statements.splice(i, 1);
- } else if (stat instanceof AST_Directive) {
- if (!member(stat.value, seen_dirs)) {
- i++;
- seen_dirs.push(stat.value);
- } else {
+ continue;
+ }
+ if (stat instanceof AST_Directive) {
+ if (member(stat.value, seen_dirs)) {
CHANGED = true;
statements.splice(i, 1);
+ continue;
}
- } else i++;
+ seen_dirs.push(stat.value);
+ }
+ if (stat instanceof AST_EmptyStatement) {
+ CHANGED = true;
+ statements.splice(i, 1);
+ continue;
+ }
+ i++;
}
}
@@ -2295,12 +2299,32 @@ merge(Compressor.prototype, {
return !value || value instanceof AST_UnaryPrefix && value.operator == "void";
}
+ function is_last_statement(body, stat) {
+ var index = body.lastIndexOf(stat);
+ if (index < 0) return false;
+ while (++index < body.length) {
+ if (!is_declaration(body[index])) return false;
+ }
+ return true;
+ }
+
+ function match_target(target) {
+ var block = self, stat, level = 0;
+ do {
+ do {
+ if (block === target) return true;
+ block = compressor.parent(level++);
+ } while (block instanceof AST_If && (stat = block));
+ } while (block instanceof AST_BlockStatement && is_last_statement(block.body, stat));
+ }
+
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;
+ if (ab instanceof AST_Return) return in_lambda && is_return_void(ab.value);
+ if (!(ab instanceof AST_LoopControl)) return false;
+ var lct = compressor.loopcontrol_target(ab);
+ if (ab instanceof AST_Continue) return match_target(loop_body(lct));
+ if (lct instanceof AST_IterationStatement) return false;
+ return match_target(lct);
}
function extract_functions() {
@@ -2327,20 +2351,14 @@ merge(Compressor.prototype, {
function next_index(i) {
for (var j = i + 1; j < statements.length; j++) {
- var stat = statements[j];
- if (!(stat instanceof AST_Var && declarations_only(stat))) {
- break;
- }
+ if (!is_declaration(statements[j])) break;
}
return j;
}
function prev_index(i) {
for (var j = i; --j >= 0;) {
- var stat = statements[j];
- if (!(stat instanceof AST_Var && declarations_only(stat))) {
- break;
- }
+ if (!is_declaration(statements[j])) break;
}
return j;
}
@@ -2383,6 +2401,10 @@ merge(Compressor.prototype, {
});
}
+ function is_declaration(stat) {
+ return stat instanceof AST_Defun || stat instanceof AST_Var && declarations_only(stat);
+ }
+
function sequencesize(statements, compressor) {
if (statements.length < 2) return;
var seq = [], n = 0;
@@ -2399,8 +2421,7 @@ 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) {
+ } else if (is_declaration(stat)) {
statements[n++] = stat;
} else {
push_seq();
diff --git a/test/compress/if_return.js b/test/compress/if_return.js
index 836fab17..90ae1210 100644
--- a/test/compress/if_return.js
+++ b/test/compress/if_return.js
@@ -594,3 +594,72 @@ iife_if_return_simple: {
}
expect_stdout: "PASS"
}
+
+nested_if_break: {
+ options = {
+ if_return: true,
+ }
+ input: {
+ for (var i = 0; i < 3; i++)
+ L1: if ("number" == typeof i) {
+ if (0 === i) break L1;
+ console.log(i);
+ }
+ }
+ expect: {
+ for (var i = 0; i < 3; i++)
+ L1: if ("number" == typeof i)
+ if (0 !== i) console.log(i);
+ }
+ expect_stdout: [
+ "1",
+ "2",
+ ]
+}
+
+nested_if_continue: {
+ options = {
+ conditionals: true,
+ if_return: true,
+ join_vars: true,
+ loops: true,
+ }
+ input: {
+ function f(n) {
+ var i = 0;
+ do {
+ if ("number" == typeof n) {
+ if (0 === n) {
+ console.log("even", i);
+ continue;
+ }
+ if (1 === n) {
+ console.log("odd", i);
+ continue;
+ }
+ i++;
+ }
+ } while (0 <= (n -= 2));
+ }
+ f(37);
+ f(42);
+ }
+ expect: {
+ function f(n) {
+ for (var i = 0;
+ "number" == typeof n
+ && (0 !== n
+ ? 1 !== n
+ ? i++
+ : console.log("odd", i)
+ : console.log("even", i)),
+ 0 <= (n -= 2););
+ }
+ f(37);
+ f(42);
+ }
+ expect_stdout: [
+ "odd 18",
+ "even 21",
+ ]
+}