fix corner case in `inline` (#3778)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 11 Apr 2020 11:54:26 +0000 (12:54 +0100)
committerGitHub <noreply@github.com>
Sat, 11 Apr 2020 11:54:26 +0000 (19:54 +0800)
fixes #3777

lib/compress.js
lib/utils.js
test/compress/functions.js

index 98724bd..e5b7bf0 100644 (file)
@@ -5820,7 +5820,7 @@ merge(Compressor.prototype, {
             }
         }
         if (is_func) {
-            var def, value;
+            var def, value, var_assigned = false;
             if (can_inline
                 && !fn.uses_arguments
                 && !fn.pinned()
@@ -5909,10 +5909,12 @@ merge(Compressor.prototype, {
             for (var i = 0; i < len; i++) {
                 var line = fn.body[i];
                 if (line instanceof AST_Var) {
-                    if (stat && !all(line.definitions, function(var_def) {
+                    var assigned = var_assigned || !all(line.definitions, function(var_def) {
                         return !var_def.value;
-                    })) {
-                        return false;
+                    });
+                    if (assigned) {
+                        var_assigned = true;
+                        if (stat) return false;
                     }
                 } else if (line instanceof AST_Defun || line instanceof AST_EmptyStatement) {
                     continue;
@@ -5932,15 +5934,11 @@ merge(Compressor.prototype, {
         }
 
         function can_substitute_directly() {
+            if (var_assigned) return;
             if (compressor.option("inline") <= 1 && fn.argnames.length) return;
-            var var_count = fn.variables.size() - 1;
-            if (var_count > fn.argnames.length) return;
-            var var_names = [];
-            if (!all(fn.argnames, function(argname) {
-                push_uniq(var_names, argname.name);
-                return argname.definition().references.length < 2;
+            if (!fn.variables.all(function(def) {
+                return def.references.length < 2 && def.orig[0] instanceof AST_SymbolFunarg;
             })) return;
-            if (var_count > var_names.length) return;
             var abort = false;
             var begin;
             var in_order = [];
index 9959305..508aba9 100644 (file)
@@ -217,6 +217,12 @@ Dictionary.prototype = {
         return this;
     },
     has: function(key) { return ("$" + key) in this._values },
+    all: function(predicate) {
+        for (var i in this._values)
+            if (!predicate(this._values[i], i.substr(1)))
+                return false;
+        return true;
+    },
     each: function(f) {
         for (var i in this._values)
             f(this._values[i], i.substr(1));
index c1522e2..4dc685b 100644 (file)
@@ -4014,3 +4014,51 @@ issue_3772: {
     }
     expect_stdout: "PASS"
 }
+
+issue_3777_1: {
+    options = {
+        inline: true,
+        reduce_vars: true,
+        side_effects: true,
+    }
+    input: {
+        (function() {
+            ff && ff(NaN);
+            function ff(a) {
+                var a = console.log("PASS");
+            }
+        })();
+    }
+    expect: {
+        (function() {
+            ff && ff(NaN);
+            function ff(a) {
+                var a = console.log("PASS");
+            }
+        })();
+    }
+    expect_stdout: "PASS"
+}
+
+issue_3777_2: {
+    options = {
+        inline: true,
+        pure_getters: "strict",
+        reduce_vars: true,
+        side_effects: true,
+        toplevel: true,
+    }
+    input: {
+        ff(ff.p);
+        function ff(a) {
+            var a = console.log("PASS");
+        }
+    }
+    expect: {
+        ff(ff.p);
+        function ff(a) {
+            var a = console.log("PASS");
+        }
+    }
+    expect_stdout: "PASS"
+}