fix corner case in `merge_vars` (#4151)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 25 Sep 2020 00:04:51 +0000 (01:04 +0100)
committerGitHub <noreply@github.com>
Fri, 25 Sep 2020 00:04:51 +0000 (08:04 +0800)
lib/compress.js
test/compress/merge_vars.js

index 883345b..517f29f 100644 (file)
@@ -4331,7 +4331,7 @@ merge(Compressor.prototype, {
 
     AST_Scope.DEFMETHOD("merge_variables", function(compressor) {
         if (!compressor.option("merge_vars")) return;
-        var self = this, segment = {};
+        var self = this, segment = {}, root;
         var first = [], last = [], index = 0;
         var declarations = new Dictionary();
         var references = Object.create(null);
@@ -4414,10 +4414,8 @@ merge(Compressor.prototype, {
             if (node instanceof AST_Scope) {
                 push();
                 segment.block = node;
-                if (node instanceof AST_Lambda && node.name) {
-                    if (node !== self) segment.loop = true;
-                    references[node.name.definition().id] = false;
-                }
+                if (node === self) root = segment;
+                if (node instanceof AST_Lambda && node.name) references[node.name.definition().id] = false;
                 descend();
                 pop();
                 return true;
@@ -4563,7 +4561,8 @@ merge(Compressor.prototype, {
                         definition: def,
                     });
                 }
-                refs.start = self;
+                if (segment.block !== self) return references[def.id] = false;
+                refs.start = root;
             }
             prev[def.id] = last.length;
             last.push({
index 559832c..b514866 100644 (file)
@@ -2766,3 +2766,37 @@ issue_4139: {
     }
     expect_stdout: "object"
 }
+
+lambda_reuse: {
+    options = {
+        merge_vars: true,
+        toplevel: true,
+    }
+    input: {
+        var a, b, f = function() {
+            console.log(a);
+        };
+        f();
+        a = "PASS";
+        b = "FAIL";
+        f();
+        if (console.log(typeof b))
+            console.log(b);
+    }
+    expect: {
+        var a, b, f = function() {
+            console.log(a);
+        };
+        f();
+        a = "PASS";
+        b = "FAIL";
+        f();
+        if (console.log(typeof b))
+            console.log(b);
+    }
+    expect_stdout: [
+        "undefined",
+        "PASS",
+        "string",
+    ]
+}