fix corner case in `merge_vars` (#4131)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 19 Sep 2020 21:36:16 +0000 (22:36 +0100)
committerGitHub <noreply@github.com>
Sat, 19 Sep 2020 21:36:16 +0000 (05:36 +0800)
fixes #4130

lib/compress.js
test/compress/merge_vars.js

index 3059c93..1f86c5b 100644 (file)
@@ -4358,6 +4358,7 @@ merge(Compressor.prototype, {
                 if (node.init) node.init.walk(tw);
                 push();
                 segment.block = node;
+                segment.loop = true;
                 if (node.condition) node.condition.walk(tw);
                 node.body.walk(tw);
                 if (node.step) node.step.walk(tw);
@@ -4368,6 +4369,7 @@ merge(Compressor.prototype, {
                 node.object.walk(tw);
                 push();
                 segment.block = node;
+                segment.loop = true;
                 node.init.walk(tw);
                 node.body.walk(tw);
                 pop();
@@ -4388,6 +4390,7 @@ merge(Compressor.prototype, {
             if (node instanceof AST_IterationStatement) {
                 push();
                 segment.block = node;
+                segment.loop = true;
                 descend();
                 pop();
                 return true;
@@ -4400,12 +4403,15 @@ merge(Compressor.prototype, {
                 return true;
             }
             if (node instanceof AST_Scope) {
+                push();
+                segment.block = node;
                 if (node instanceof AST_Lambda) {
+                    if (node.name) {
+                        if (node !== self) segment.loop = true;
+                        references[node.name.definition().id] = false;
+                    }
                     references[node.variables.get("arguments").id] = false;
-                    if (node.name) references[node.name.definition().id] = false;
                 }
-                push();
-                segment.block = node;
                 descend();
                 pop();
                 return true;
@@ -4487,7 +4493,9 @@ merge(Compressor.prototype, {
                 var id = tail.definition.id;
                 var tail_refs = references[id];
                 if (!tail_refs) continue;
-                if (!mergeable(head_refs, tail_refs)) {
+                if (head_refs.start.block !== tail_refs.start.block
+                    || !mergeable(head_refs, tail_refs)
+                    || head_refs.start.loop && !mergeable(tail_refs, head_refs)) {
                     skipped.unshift(tail);
                     continue;
                 }
@@ -4560,7 +4568,6 @@ merge(Compressor.prototype, {
         }
 
         function mergeable(head, tail) {
-            if (head.start.block !== tail.start.block) return false;
             return must_visit(head.start, head.end) || must_visit(head.start, tail.start);
         }
     });
index 0641be7..d48b117 100644 (file)
@@ -2662,3 +2662,42 @@ issue_4126_2: {
     }
     expect_stdout: "undefined"
 }
+
+issue_4130: {
+    options = {
+        merge_vars: true,
+        side_effects: true,
+        toplevel: true,
+    }
+    input: {
+        var a = 2;
+        while (a)
+            try {
+                console.log(a);
+            } catch (e) {
+                var b = 0;
+            } finally {
+                b && console.log("FAIL");
+                var c = --a;
+                for (var k in c)
+                    c;
+            }
+    }
+    expect: {
+        var a = 2;
+        while (a)
+            try {
+                console.log(a);
+            } catch (e) {
+                var b = 0;
+            } finally {
+                b && console.log("FAIL");
+                var c = --a;
+                for (var k in c);
+            }
+    }
+    expect_stdout: [
+        "2",
+        "1",
+    ]
+}