fix corner case in `inline` (#3343)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 16 Mar 2019 21:31:40 +0000 (05:31 +0800)
committerGitHub <noreply@github.com>
Sat, 16 Mar 2019 21:31:40 +0000 (05:31 +0800)
lib/compress.js
test/compress/functions.js

index 1aa7556..6f1ffe7 100644 (file)
@@ -5005,8 +5005,7 @@ merge(Compressor.prototype, {
         }
 
         function can_inject_vars(catches, safe_to_inject) {
-            var len = fn.body.length;
-            for (var i = 0; i < len; i++) {
+            for (var i = 0, len = fn.body.length; i < len; i++) {
                 var stat = fn.body[i];
                 if (!(stat instanceof AST_Var)) continue;
                 if (!safe_to_inject) return false;
@@ -5035,7 +5034,8 @@ merge(Compressor.prototype, {
                     if (scope.fixed_value() instanceof AST_Scope) return false;
                 }
             } while (!(scope instanceof AST_Scope));
-            var safe_to_inject = !(scope instanceof AST_Toplevel) || compressor.toplevel.vars;
+            var safe_to_inject = (!(scope instanceof AST_Toplevel) || compressor.toplevel.vars)
+                && fn.parent_scope === compressor.find_parent(AST_Scope);
             var inline = compressor.option("inline");
             if (!can_inject_vars(catches, inline >= 3 && safe_to_inject)) return false;
             if (!can_inject_args(catches, inline >= 2 && safe_to_inject)) return false;
index 6e9ff3b..4d243a8 100644 (file)
@@ -1398,6 +1398,8 @@ recursive_inline_2: {
 issue_2657: {
     options = {
         inline: true,
+        passes: 2,
+        reduce_funcs: true,
         reduce_vars: true,
         sequences: true,
         unused: true,
@@ -2467,6 +2469,7 @@ issue_3297_3: {
         inline: true,
         join_vars: true,
         passes: 3,
+        reduce_funcs: true,
         reduce_vars: true,
         sequences: true,
         side_effects: true,
@@ -2505,18 +2508,18 @@ issue_3297_3: {
         }).processBulk([1, 2, 3]);
     }
     expect: {
-        function function1(c) {
+        function function1(u) {
             return {
-                processBulk: function n(o) {
-                    var r, t, u = c();
-                    o && 0 < o.length && (r = {
-                        param1: o.shift(),
+                processBulk: function n(r) {
+                    var o, t = u();
+                    r && 0 < r.length && (o = {
+                        param1: r.shift(),
                         param2: {
-                            subparam1: u
+                            subparam1: t
                         }
-                    }, t = function() {
-                        n(o);
-                    }, console.log(JSON.stringify(r)), t());
+                    },
+                    console.log(JSON.stringify(o)),
+                    n(r));
                 }
             };
         }
@@ -2530,3 +2533,140 @@ issue_3297_3: {
         '{"param1":3,"param2":{"subparam1":42}}',
     ]
 }
+
+cross_references_1: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        var Math = {
+            square: function(n) {
+                return n * n;
+            }
+        };
+        console.log((function(factory) {
+            return factory();
+        })(function() {
+            return function(Math) {
+                return function(n) {
+                    return Math.square(n);
+                };
+            }(Math);
+        })(3));
+    }
+    expect: {
+        var Math = {
+            square: function(n) {
+                return n * n;
+            }
+        };
+        console.log(function(Math) {
+            return function(n) {
+                return Math.square(n);
+            };
+        }(Math)(3));
+    }
+    expect_stdout: "9"
+}
+
+cross_references_2: {
+    options = {
+        collapse_vars: true,
+        evaluate: true,
+        hoist_props: true,
+        inline: true,
+        passes: 4,
+        pure_getters: true,
+        reduce_vars: true,
+        sequences: true,
+        side_effects: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var Math = {
+            square: function(n) {
+                return n * n;
+            }
+        };
+        console.log((function(factory) {
+            return factory();
+        })(function() {
+            return function(Math) {
+                return function(n) {
+                    return Math.square(n);
+                };
+            }(Math);
+        })(3));
+    }
+    expect: {
+        console.log(9);
+    }
+    expect_stdout: "9"
+}
+
+cross_references_3: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        unused: true,
+    }
+    input: {
+        var Math = {
+            square: function(n) {
+                return n * n;
+            },
+            cube: function(n) {
+                return n * n * n;
+            }
+        };
+        console.log(function(factory) {
+            return factory();
+        }(function() {
+            return function(Math) {
+                return function(n) {
+                    Math = {
+                        square: function(x) {
+                            return "(SQUARE" + x + ")";
+                        },
+                        cube: function(x) {
+                            return "(CUBE" + x + ")";
+                        }
+                    };
+                    return Math.square(n) + Math.cube(n);
+                };
+            }(Math);
+        })(2));
+        console.log(Math.square(3), Math.cube(3));
+    }
+    expect: {
+        var Math = {
+            square: function(n) {
+                return n * n;
+            },
+            cube: function(n) {
+                return n * n * n;
+            }
+        };
+        console.log(function(Math) {
+            return function(n) {
+                Math = {
+                    square: function(x) {
+                        return "(SQUARE" + x + ")";
+                    },
+                    cube: function(x) {
+                        return "(CUBE" + x + ")";
+                    }
+                };
+                return Math.square(n) + Math.cube(n);
+            };
+        }(Math)(2));
+        console.log(Math.square(3), Math.cube(3));
+    }
+    expect_stdout: [
+        "(SQUARE2)(CUBE2)",
+        "9 27",
+    ]
+}