fix `if_return` on `AST_Defun` (#2010)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 27 May 2017 05:41:49 +0000 (13:41 +0800)
committerGitHub <noreply@github.com>
Sat, 27 May 2017 05:41:49 +0000 (13:41 +0800)
Previous fiix for #1052 perturbs declaration order of functions which leads to incorrect behaviour under "use strict".

lib/compress.js
test/compress/issue-1052.js

index bd017e1..efa8e98 100644 (file)
@@ -965,15 +965,15 @@ merge(Compressor.prototype, {
                             CHANGED = true;
                             stat = stat.clone();
                             stat.condition = stat.condition.negate(compressor);
+                            var funs = extract_functions_from_statement_array(ret);
                             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: body
                             });
                             stat.alternative = value ? make_node(AST_SimpleStatement, value, {
                                 body: value.expression
                             }) : null;
-                            ret = funs.concat([ stat.transform(compressor) ]);
+                            ret = [ stat.transform(compressor) ].concat(funs);
                             continue loop;
                         }
                         //---
index 0a77f00..e3dc732 100644 (file)
@@ -1,90 +1,91 @@
 multiple_functions: {
-    options = { if_return: true, hoist_funs: false };
+    options = {
+        hoist_funs: false,
+        if_return: true,
+    }
     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 );
+            function f() {}
+            function g() {}
         } )();
     }
 }
 
 single_function: {
-    options = { if_return: true, hoist_funs: false };
+    options = {
+        hoist_funs: false,
+        if_return: true,
+    }
     input: {
         ( function() {
             if ( !window ) {
                 return;
             }
-
             function f() {}
         } )();
     }
     expect: {
         ( function() {
-            function f() {}
-
             if ( window );
+            function f() {}
         } )();
     }
 }
 
 deeply_nested: {
-    options = { if_return: true, hoist_funs: false };
+    options = {
+        hoist_funs: false,
+        if_return: true,
+    }
     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);
+            function f() {}
+            function g() {}
+            function h() {}
         } )();
     }
 }
 
 not_hoisted_when_already_nested: {
-    options = { if_return: true, hoist_funs: false };
+    options = {
+        hoist_funs: false,
+        if_return: true,
+    }
     input: {
         ( function() {
             if ( !window ) {
                 return;
             }
-
             if ( foo ) function f() {}
-
         } )();
     }
     expect: {
@@ -94,3 +95,48 @@ not_hoisted_when_already_nested: {
         } )();
     }
 }
+
+defun_if_return: {
+    options = {
+        hoist_funs: false,
+        if_return: true,
+    }
+    input: {
+        function e() {
+            function f() {}
+            if (!window) return;
+            else function g() {}
+            function h() {}
+        }
+    }
+    expect: {
+        function e() {
+            function f() {}
+            if (window) function g() {}
+            function h() {}
+        }
+    }
+}
+
+defun_hoist_funs: {
+    options = {
+        hoist_funs: true,
+        if_return: true,
+    }
+    input: {
+        function e() {
+            function f() {}
+            if (!window) return;
+            else function g() {}
+            function h() {}
+        }
+    }
+    expect: {
+        function e() {
+            function f() {}
+            function g() {}
+            function h() {}
+            !window;
+        }
+    }
+}