fix corner cases related to `AST_Hole` (#3994)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sat, 13 Jun 2020 14:24:57 +0000 (15:24 +0100)
committerGitHub <noreply@github.com>
Sat, 13 Jun 2020 14:24:57 +0000 (15:24 +0100)
lib/compress.js
test/compress/evaluate.js
test/compress/properties.js

index a3a4a63..860eae1 100644 (file)
@@ -3369,9 +3369,10 @@ merge(Compressor.prototype, {
                 var elements = [];
                 for (var i = 0; i < this.elements.length; i++) {
                     var element = this.elements[i];
+                    if (element instanceof AST_Hole) continue;
                     var value = element._eval(compressor, ignore_side_effects, cached, depth);
                     if (element === value) return this;
-                    elements.push(value);
+                    elements[i] = value;
                 }
                 return elements;
             }
@@ -8446,7 +8447,8 @@ merge(Compressor.prototype, {
             var elements = expr.elements;
             var retValue = elements[index];
             if (safe_to_flatten(retValue, compressor)) {
-                var flatten = true;
+                var is_hole = retValue instanceof AST_Hole;
+                var flatten = !is_hole;
                 var values = [];
                 for (var i = elements.length; --i > index;) {
                     var value = elements[i].drop_side_effect_free(compressor);
@@ -8455,12 +8457,16 @@ merge(Compressor.prototype, {
                         if (flatten && value.has_side_effects(compressor)) flatten = false;
                     }
                 }
-                retValue = retValue instanceof AST_Hole ? make_node(AST_Undefined, retValue) : retValue;
                 if (!flatten) values.unshift(retValue);
                 while (--i >= 0) {
                     var value = elements[i].drop_side_effect_free(compressor);
-                    if (value) values.unshift(value);
-                    else index--;
+                    if (value) {
+                        values.unshift(value);
+                    } else if (is_hole) {
+                        values.unshift(make_node(AST_Hole, elements[i]));
+                    } else {
+                        index--;
+                    }
                 }
                 if (flatten) {
                     values.push(retValue);
index da928b3..e5ecc6d 100644 (file)
@@ -558,34 +558,45 @@ unsafe_array: {
         unsafe: true,
     }
     input: {
-        console.log(
-            [1, , 3][1],
-            [1, 2, 3, a] + 1,
-            [1, 2, 3, 4] + 1,
-            [1, 2, 3, a][0] + 1,
-            [1, 2, 3, 4][0] + 1,
-            [1, 2, 3, 4][6 - 5] + 1,
-            [1, , 3, 4][6 - 5] + 1,
-            [[1, 2], [3, 4]][0] + 1,
-            [[1, 2], [3, 4]][6 - 5][1] + 1,
-            [[1, 2], , [3, 4]][6 - 5][1] + 1
-        );
+        var a = "PASS";
+        Array.prototype[1] = a;
+        console.log([1, , 3][1]);
+        console.log([1, 2, 3, a] + 1);
+        console.log([1, 2, 3, 4] + 1);
+        console.log([1, 2, 3, a][0] + 1);
+        console.log([1, 2, 3, 4][0] + 1);
+        console.log([1, 2, 3, 4][6 - 5] + 1);
+        console.log([1, , 3, 4][6 - 5] + 1);
+        console.log([[1, 2], [3, 4]][0] + 1);
+        console.log([[1, 2], [3, 4]][6 - 5][1] + 1);
+        console.log([[1, 2], , [3, 4]][6 - 5][1] + 1);
     }
     expect: {
-        console.log(
-            void 0,
-            [1, 2, 3, a] + 1,
-            "1,2,3,41",
-            [1, 2, 3, a][0] + 1,
-            2,
-            3,
-            NaN,
-            "1,21",
-            5,
-            (void 0)[1] + 1
-        );
+        var a = "PASS";
+        Array.prototype[1] = a;
+        console.log([1, , 3][1]);
+        console.log([1, 2, 3, a] + 1);
+        console.log("1,2,3,41");
+        console.log([1, 2, 3, a][0] + 1);
+        console.log(2);
+        console.log(3);
+        console.log([1, , 3, 4][1] + 1);
+        console.log("1,21");
+        console.log(5);
+        console.log([[1, 2], , [3, 4]][1][1] + 1);
     }
-    expect_stdout: true
+    expect_stdout: [
+        "PASS",
+        "1,2,3,PASS1",
+        "1,2,3,41",
+        "2",
+        "2",
+        "3",
+        "PASS1",
+        "1,21",
+        "5",
+        "A1",
+    ]
 }
 
 unsafe_string: {
index 364eb97..af57c6b 100644 (file)
@@ -1046,16 +1046,22 @@ array_hole: {
         side_effects: true,
     }
     input: {
-        console.log(
-            [ 1, 2, , 3][1],
-            [ 1, 2, , 3][2],
-            [ 1, 2, , 3][3]
-        );
+        Array.prototype[2] = "PASS";
+        console.log([ 1, 2, , 3 ][1]);
+        console.log([ 1, 2, , 3 ][2]);
+        console.log([ 1, 2, , 3 ][3]);
     }
     expect: {
-        console.log(2, void 0, 3);
+        Array.prototype[2] = "PASS";
+        console.log(2);
+        console.log([ , , , ][2]);
+        console.log(3);
     }
-    expect_stdout: "2 undefined 3"
+    expect_stdout: [
+        "2",
+        "PASS",
+        "3",
+    ]
 }
 
 new_this: {