Hoist functions when reversing if (x) return; ... vs. if (!x) ...
authorRichard van Velzen <rvanvelzen@experty.com>
Sat, 23 Apr 2016 21:48:33 +0000 (23:48 +0200)
committerRichard van Velzen <rvanvelzen@experty.com>
Sat, 23 Apr 2016 21:48:33 +0000 (23:48 +0200)
Fixes #1052

lib/compress.js
test/compress/issue-1052.js [new file with mode: 0644]

index 53618ae..2bcfcf3 100644 (file)
@@ -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 (file)
index 0000000..067eea4
--- /dev/null
@@ -0,0 +1,27 @@
+hoist_funs_when_handling_if_return_rerversal: {
+    options = { if_return: true, hoist_funs: false };
+    input: {
+        "use strict";
+
+        ( function() {
+            if ( !window ) {
+                return;
+            }
+
+            function f() {}
+            function g() {}
+        } )();
+    }
+    expect: {
+        "use strict";
+
+        ( function() {
+            function f() {}
+            function g() {}
+
+            // NOTE: other compression steps will reduce this
+            // down to just `window`.
+            if ( window );
+        } )();
+    }
+}