fix corner case in `assignments` (#3407)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 11 May 2019 19:52:46 +0000 (03:52 +0800)
committerGitHub <noreply@github.com>
Sat, 11 May 2019 19:52:46 +0000 (03:52 +0800)
fixes #3406

lib/compress.js
test/compress/assignment.js
test/compress/dead-code.js
test/compress/drop-unused.js
test/compress/sequences.js

index b63c051..638fb7c 100644 (file)
@@ -5395,7 +5395,8 @@ merge(Compressor.prototype, {
 
     OPT(AST_UnaryPrefix, function(self, compressor) {
         var e = self.expression;
-        if (self.operator == "delete"
+        if (compressor.option("evaluate")
+            && self.operator == "delete"
             && !(e instanceof AST_SymbolRef
                 || e instanceof AST_PropAccess
                 || is_identifier_atom(e))) {
@@ -6254,6 +6255,7 @@ merge(Compressor.prototype, {
         if (compressor.option("dead_code")
             && self.left instanceof AST_SymbolRef
             && (def = self.left.definition()).scope === compressor.find_parent(AST_Lambda)) {
+            if (self.left.is_immutable()) return strip_assignment();
             var level = 0, node, parent = self;
             do {
                 node = parent;
@@ -6261,16 +6263,12 @@ merge(Compressor.prototype, {
                 if (parent instanceof AST_Exit) {
                     if (in_try(level, parent)) break;
                     if (is_reachable(def.scope, [ def ])) break;
-                    if (self.operator == "=") return self.right.optimize(compressor);
                     def.fixed = false;
-                    return make_node(AST_Binary, self, {
-                        operator: self.operator.slice(0, -1),
-                        left: self.left,
-                        right: self.right
-                    }).optimize(compressor);
+                    return strip_assignment();
                 }
             } while (parent instanceof AST_Binary && parent.right === node
-                || parent instanceof AST_Sequence && parent.tail_node() === node);
+                || parent instanceof AST_Sequence && parent.tail_node() === node
+                || parent instanceof AST_UnaryPrefix);
         }
         self = self.lift_sequences(compressor);
         if (!compressor.option("assignments")) return self;
@@ -6302,13 +6300,6 @@ merge(Compressor.prototype, {
                 expression: self.left
             });
         }
-        if (!compressor.option("ie8") && self.left instanceof AST_Symbol && self.left.is_immutable()) {
-            return (self.operator == "=" ? self.right : make_node(AST_Binary, self, {
-                operator: self.operator.slice(0, -1),
-                left: self.left,
-                right: self.right
-            })).optimize(compressor);
-        }
         return self;
 
         function in_try(level, node) {
@@ -6325,6 +6316,14 @@ merge(Compressor.prototype, {
                 }
             }
         }
+
+        function strip_assignment() {
+            return (self.operator != "=" ? make_node(AST_Binary, self, {
+                operator: self.operator.slice(0, -1),
+                left: self.left,
+                right: self.right
+            }) : maintain_this_binding(compressor, compressor.parent(), self, self.right)).optimize(compressor);
+        }
     });
 
     OPT(AST_Conditional, function(self, compressor) {
index 191b892..ece0185 100644 (file)
@@ -311,39 +311,3 @@ issue_3375: {
     }
     expect_stdout: "string"
 }
-
-issue_3402: {
-    options = {
-        assignments: true,
-        evaluate: true,
-        functions: true,
-        passes: 2,
-        reduce_vars: true,
-        side_effects: true,
-        toplevel: true,
-        typeofs: true,
-        unused: true,
-    }
-    input: {
-        var f = function f() {
-            f = 42;
-            console.log(typeof f);
-        };
-        "function" == typeof f && f();
-        "function" == typeof f && f();
-        console.log(typeof f);
-    }
-    expect: {
-        function f() {
-            console.log(typeof f);
-        }
-        f();
-        f();
-        console.log(typeof f);
-    }
-    expect_stdout: [
-        "function",
-        "function",
-        "function",
-    ]
-}
index 5f1ca71..190a324 100644 (file)
@@ -960,3 +960,56 @@ unsafe_string_replace: {
     }
     expect_stdout: "PASS"
 }
+
+issue_3402: {
+    options = {
+        dead_code: true,
+        evaluate: true,
+        functions: true,
+        passes: 2,
+        reduce_vars: true,
+        side_effects: true,
+        toplevel: true,
+        typeofs: true,
+        unused: true,
+    }
+    input: {
+        var f = function f() {
+            f = 42;
+            console.log(typeof f);
+        };
+        "function" == typeof f && f();
+        "function" == typeof f && f();
+        console.log(typeof f);
+    }
+    expect: {
+        function f() {
+            console.log(typeof f);
+        }
+        f();
+        f();
+        console.log(typeof f);
+    }
+    expect_stdout: [
+        "function",
+        "function",
+        "function",
+    ]
+}
+
+issue_3406: {
+    options = {
+        dead_code: true,
+    }
+    input: {
+        console.log(function f(a) {
+            return delete (f = a);
+        }());
+    }
+    expect: {
+        console.log(function f(a) {
+            return delete (0, a);
+        }());
+    }
+    expect_stdout: "true"
+}
index 0869749..d7f3cf7 100644 (file)
@@ -1005,7 +1005,7 @@ issue_1715_4: {
 delete_assign_1: {
     options = {
         booleans: true,
-        side_effects: true,
+        evaluate: true,
         toplevel: true,
         unused: true,
     }
@@ -1024,7 +1024,7 @@ delete_assign_1: {
         console.log((1 / 0, !0));
         console.log((1 / 0, !0));
         console.log((NaN, !0));
-        console.log((0 / 0, !0));
+        console.log((NaN, !0));
     }
     expect_stdout: true
 }
@@ -1032,8 +1032,8 @@ delete_assign_1: {
 delete_assign_2: {
     options = {
         booleans: true,
+        evaluate: true,
         keep_infinity: true,
-        side_effects: true,
         toplevel: true,
         unused: true,
     }
@@ -1052,7 +1052,7 @@ delete_assign_2: {
         console.log((Infinity, !0));
         console.log((1 / 0, !0));
         console.log((NaN, !0));
-        console.log((0 / 0, !0));
+        console.log((NaN, !0));
     }
     expect_stdout: true
 }
index 47dd4c4..08a0679 100644 (file)
@@ -490,6 +490,7 @@ issue_1758: {
 delete_seq_1: {
     options = {
         booleans: true,
+        evaluate: true,
         side_effects: true,
     }
     input: {
@@ -514,6 +515,7 @@ delete_seq_1: {
 delete_seq_2: {
     options = {
         booleans: true,
+        evaluate: true,
         side_effects: true,
     }
     input: {
@@ -538,6 +540,7 @@ delete_seq_2: {
 delete_seq_3: {
     options = {
         booleans: true,
+        evaluate: true,
         keep_infinity: true,
         side_effects: true,
     }
@@ -563,6 +566,7 @@ delete_seq_3: {
 delete_seq_4: {
     options = {
         booleans: true,
+        evaluate: true,
         sequences: true,
         side_effects: true,
     }
@@ -590,6 +594,7 @@ delete_seq_4: {
 delete_seq_5: {
     options = {
         booleans: true,
+        evaluate: true,
         keep_infinity: true,
         sequences: true,
         side_effects: true,
@@ -618,6 +623,7 @@ delete_seq_5: {
 delete_seq_6: {
     options = {
         booleans: true,
+        evaluate: true,
         side_effects: true,
     }
     input: {