aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMihai Bazon <mihai.bazon@gmail.com>2016-04-26 22:09:52 +0300
committerMihai Bazon <mihai.bazon@gmail.com>2016-04-26 22:09:52 +0300
commit65887d9a56d8f3eb1e75cd924b4fd2c9065d0e11 (patch)
tree3fd4a4743fe837f53f8a62d90bbf38b089a9eefa
parentc55dd5ed74888d533cf8402c6ba3612916ba2885 (diff)
parente9224ab4441ddb352566a52b84f1384bf5b8a8d8 (diff)
downloadtracifyjs-65887d9a56d8f3eb1e75cd924b4fd2c9065d0e11.tar.gz
tracifyjs-65887d9a56d8f3eb1e75cd924b4fd2c9065d0e11.zip
Merge pull request #1053 from rvanvelzen/hoist_if_return_funs
Hoist functions when reversing if (x) return; ... vs. if (!x) ...
-rw-r--r--lib/compress.js18
-rw-r--r--test/compress/issue-1052.js96
2 files changed, 112 insertions, 2 deletions
diff --git a/lib/compress.js b/lib/compress.js
index 53618ae1..2bcfcf30 100644
--- a/lib/compress.js
+++ b/lib/compress.js
@@ -578,11 +578,13 @@ merge(Compressor.prototype, {
CHANGED = true;
stat = stat.clone();
stat.condition = stat.condition.negate(compressor);
+ var body = as_statement_array(stat.alternative).concat(ret);
+ var funs = extract_functions_from_statement_array(body);
stat.body = make_node(AST_BlockStatement, stat, {
- body: as_statement_array(stat.alternative).concat(ret)
+ body: body
});
stat.alternative = null;
- ret = [ stat.transform(compressor) ];
+ ret = funs.concat([ stat.transform(compressor) ]);
continue loop;
}
//---
@@ -840,6 +842,18 @@ merge(Compressor.prototype, {
};
+ function extract_functions_from_statement_array(statements) {
+ var funs = [];
+ for (var i = statements.length - 1; i >= 0; --i) {
+ var stat = statements[i];
+ if (stat instanceof AST_Defun) {
+ statements.splice(i, 1);
+ funs.unshift(stat);
+ }
+ }
+ return funs;
+ }
+
function extract_declarations_from_unreachable_code(compressor, stat, target) {
if (!(stat instanceof AST_Defun)) {
compressor.warn("Dropping unreachable code [{file}:{line},{col}]", stat.start);
diff --git a/test/compress/issue-1052.js b/test/compress/issue-1052.js
new file mode 100644
index 00000000..0a77f006
--- /dev/null
+++ b/test/compress/issue-1052.js
@@ -0,0 +1,96 @@
+multiple_functions: {
+ options = { if_return: true, hoist_funs: false };
+ input: {
+ ( function() {
+ if ( !window ) {
+ return;
+ }
+
+ function f() {}
+ function g() {}
+ } )();
+ }
+ expect: {
+ ( function() {
+ function f() {}
+ function g() {}
+
+ // NOTE: other compression steps will reduce this
+ // down to just `window`.
+ if ( window );
+ } )();
+ }
+}
+
+single_function: {
+ options = { if_return: true, hoist_funs: false };
+ input: {
+ ( function() {
+ if ( !window ) {
+ return;
+ }
+
+ function f() {}
+ } )();
+ }
+ expect: {
+ ( function() {
+ function f() {}
+
+ if ( window );
+ } )();
+ }
+}
+
+deeply_nested: {
+ options = { if_return: true, hoist_funs: false };
+ input: {
+ ( function() {
+ if ( !window ) {
+ return;
+ }
+
+ function f() {}
+ function g() {}
+
+ if ( !document ) {
+ return;
+ }
+
+ function h() {}
+ } )();
+ }
+ expect: {
+ ( function() {
+ function f() {}
+ function g() {}
+
+ function h() {}
+
+ // NOTE: other compression steps will reduce this
+ // down to just `window`.
+ if ( window )
+ if (document);
+ } )();
+ }
+}
+
+not_hoisted_when_already_nested: {
+ options = { if_return: true, hoist_funs: false };
+ input: {
+ ( function() {
+ if ( !window ) {
+ return;
+ }
+
+ if ( foo ) function f() {}
+
+ } )();
+ }
+ expect: {
+ ( function() {
+ if ( window )
+ if ( foo ) function f() {}
+ } )();
+ }
+}