aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Lam S.L <alexlamsl@gmail.com>2020-10-05 01:26:59 +0100
committerGitHub <noreply@github.com>2020-10-05 08:26:59 +0800
commit813ac3ba9663d4123043aa823da59b6c3387f30f (patch)
treea2e8f0fb11a559f46b9740b81eaad42a02b42041
parent220dc95c0d212ad4f3b97fcd937c4370ae5345dd (diff)
downloadtracifyjs-813ac3ba9663d4123043aa823da59b6c3387f30f.tar.gz
tracifyjs-813ac3ba9663d4123043aa823da59b6c3387f30f.zip
enhance `loops` (#4180)
-rw-r--r--lib/compress.js61
-rw-r--r--test/compress/loops.js46
2 files changed, 88 insertions, 19 deletions
diff --git a/lib/compress.js b/lib/compress.js
index cb8b0caf..4534d9c8 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -1180,6 +1180,16 @@ merge(Compressor.prototype, {
|| node instanceof AST_Undefined;
}
+ function declarations_only(node) {
+ return all(node.definitions, function(var_def) {
+ return !var_def.value;
+ });
+ }
+
+ function is_declaration(stat) {
+ return stat instanceof AST_Defun || stat instanceof AST_Var && declarations_only(stat);
+ }
+
function tighten_body(statements, compressor) {
var in_loop, in_try, scope;
find_loop_scope_try();
@@ -2407,16 +2417,6 @@ merge(Compressor.prototype, {
});
}
- function declarations_only(node) {
- return all(node.definitions, function(var_def) {
- return !var_def.value;
- });
- }
-
- 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;
@@ -4268,13 +4268,17 @@ merge(Compressor.prototype, {
return self;
});
+ function trim_block(stat) {
+ switch (stat.body.length) {
+ case 1: return stat.body[0];
+ case 0: return make_node(AST_EmptyStatement, stat);
+ }
+ return stat;
+ }
+
OPT(AST_BlockStatement, function(self, compressor) {
self.body = tighten_body(self.body, compressor);
- switch (self.body.length) {
- case 1: return self.body[0];
- case 0: return make_node(AST_EmptyStatement, self);
- }
- return self;
+ return trim_block(self);
});
OPT(AST_Function, function(self, compressor) {
@@ -5847,6 +5851,33 @@ merge(Compressor.prototype, {
}).optimize(compressor);
}
}
+ if (self.body instanceof AST_BlockStatement) {
+ var body = self.body.body;
+ for (var i = body.length; --i >= 0;) {
+ var stat = body[i];
+ if (stat instanceof AST_If
+ && !stat.alternative
+ && stat.body instanceof AST_Break
+ && compressor.loopcontrol_target(stat.body) === compressor.self()) {
+ self.condition = make_node(AST_Binary, self, {
+ operator: "&&",
+ left: stat.condition.negate(compressor),
+ right: self.condition,
+ });
+ body.splice(i, 1);
+ } else if (stat instanceof AST_SimpleStatement) {
+ self.condition = make_sequence(self, [
+ stat.body,
+ self.condition,
+ ]);
+ body.splice(i, 1);
+ } else if (!is_declaration(stat)) {
+ break;
+ }
+ }
+ self.body = trim_block(self.body);
+ }
+ if (self.body instanceof AST_EmptyStatement) return make_node(AST_For, self, self).optimize(compressor);
if (self.body instanceof AST_SimpleStatement) return make_node(AST_For, self, {
condition: make_sequence(self.condition, [
self.body.body,
diff --git a/test/compress/loops.js b/test/compress/loops.js
index cbc1166f..b8d351ad 100644
--- a/test/compress/loops.js
+++ b/test/compress/loops.js
@@ -201,7 +201,7 @@ evaluate: {
}
}
-issue_1532: {
+issue_1532_1: {
options = {
evaluate: true,
loops: true,
@@ -210,18 +210,56 @@ issue_1532: {
function f(x, y) {
do {
if (x) break;
- foo();
+ console.log(y);
} while (false);
}
+ f(null, "PASS");
+ f(42, "FAIL");
}
expect: {
function f(x, y) {
+ for (; !x && (console.log(y), false););
+ }
+ f(null, "PASS");
+ f(42, "FAIL");
+ }
+ expect_stdout: "PASS"
+}
+
+issue_1532_2: {
+ options = {
+ evaluate: true,
+ loops: true,
+ }
+ input: {
+ function f(x, y) {
do {
- if (x) break;
- foo();
+ if (x) {
+ console.log(x);
+ break;
+ }
+ console.log(y);
} while (false);
}
+ f(null, "PASS");
+ f(42, "FAIL");
+ }
+ expect: {
+ function f(x, y) {
+ do {
+ if (x) {
+ console.log(x);
+ break;
+ }
+ } while (console.log(y), false);
+ }
+ f(null, "PASS");
+ f(42, "FAIL");
}
+ expect_stdout: [
+ "PASS",
+ "42",
+ ]
}
issue_186: {