enhance `dead_code` (#3575)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 8 Nov 2019 05:45:28 +0000 (13:45 +0800)
committerGitHub <noreply@github.com>
Fri, 8 Nov 2019 05:45:28 +0000 (13:45 +0800)
lib/compress.js
test/compress/dead-code.js

index 0d19640..43ee112 100644 (file)
@@ -6543,23 +6543,28 @@ merge(Compressor.prototype, {
                     }
                 }
             } else if (self.left instanceof AST_SymbolRef) {
+                if (self.left.is_immutable()) return strip_assignment();
                 var def = self.left.definition();
-                if (def.scope === compressor.find_parent(AST_Lambda)) {
-                    if (self.left.is_immutable()) return strip_assignment();
-                    var level = 0, node, parent = self;
-                    do {
-                        node = parent;
-                        parent = compressor.parent(level++);
-                        if (parent instanceof AST_Exit) {
-                            if (in_try(level, parent)) break;
-                            if (is_reachable(def.scope, [ def ])) break;
-                            def.fixed = false;
-                            return strip_assignment();
-                        }
-                    } while (parent instanceof AST_Binary && parent.right === node
-                        || parent instanceof AST_Sequence && parent.tail_node() === node
-                        || parent instanceof AST_UnaryPrefix);
-                }
+                var local = def.scope.resolve() === compressor.find_parent(AST_Lambda);
+                var level = 0, node, parent = self;
+                do {
+                    node = parent;
+                    parent = compressor.parent(level++);
+                    if (parent instanceof AST_Assign) {
+                        if (!(parent.left instanceof AST_SymbolRef)) continue;
+                        if (parent.left.definition() !== def) continue;
+                        def.fixed = false;
+                        return strip_assignment();
+                    } else if (parent instanceof AST_Exit) {
+                        if (!local) break;
+                        if (in_try(level, parent)) break;
+                        if (is_reachable(def.scope, [ def ])) break;
+                        def.fixed = false;
+                        return strip_assignment();
+                    }
+                } while (parent instanceof AST_Binary && parent.right === node
+                    || parent instanceof AST_Sequence && parent.tail_node() === node
+                    || parent instanceof AST_UnaryPrefix);
             }
         }
         self = self.lift_sequences(compressor);
@@ -6599,7 +6604,7 @@ merge(Compressor.prototype, {
             self.right = make_node(AST_Null, right);
             var may_throw = node.may_throw(compressor);
             self.right = right;
-            var scope = self.left.definition().scope;
+            var scope = self.left.definition().scope.resolve();
             var parent;
             while ((parent = compressor.parent(level++)) !== scope) {
                 if (parent instanceof AST_Try) {
index 93fc9f4..abc7384 100644 (file)
@@ -1064,3 +1064,41 @@ issue_3552: {
     }
     expect_stdout: "PASS"
 }
+
+unreachable_assign: {
+    options = {
+        dead_code: true,
+    }
+    input: {
+        console.log(A = "P" + (A = "A" + (B = "S" + (A = B = "S"))), A, B);
+    }
+    expect: {
+        console.log(A = "P" + "A" + (B = "S" + "S"), A, B);
+    }
+    expect_stdout: "PASS PASS SS"
+}
+
+catch_return_assign: {
+    options = {
+        dead_code: true,
+    }
+    input: {
+        console.log(function() {
+            try {
+                throw "FAIL";
+            } catch (e) {
+                return e = "PASS";
+            }
+        }());
+    }
+    expect: {
+        console.log(function() {
+            try {
+                throw "FAIL";
+            } catch (e) {
+                return "PASS";
+            }
+        }());
+    }
+    expect_stdout: "PASS"
+}