fix corner case in `properties` (#4330)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 6 Dec 2020 05:59:04 +0000 (05:59 +0000)
committerGitHub <noreply@github.com>
Sun, 6 Dec 2020 05:59:04 +0000 (13:59 +0800)
fixes #4329

lib/compress.js
test/compress/spread.js

index a78cf6e..82474b5 100644 (file)
@@ -9689,13 +9689,26 @@ merge(Compressor.prototype, {
         });
     });
 
+    function is_integer(key) {
+        return /^[0-9]+$/.test(key);
+    }
+
     OPT(AST_Spread, function(self, compressor) {
         if (compressor.option("properties")) {
             var exp = self.expression;
             if (compressor.parent() instanceof AST_Object) {
                 if (exp instanceof AST_Object && all(exp.properties, function(node) {
                     return node instanceof AST_ObjectKeyVal;
-                })) return List.splice(exp.properties);
+                })) return List.splice(exp.properties.map(function(node) {
+                    var key = node.key;
+                    if (!(key instanceof AST_Node) && is_integer(key)) {
+                        node = node.clone();
+                        node.key = make_node(AST_Number, node, {
+                            value: +key
+                        });
+                    }
+                    return node;
+                }));
             } else if (exp instanceof AST_Array) return List.splice(exp.elements.map(function(node) {
                 return node instanceof AST_Hole ? make_node(AST_Undefined, node).optimize(compressor) : node;
             }));
@@ -9971,7 +9984,7 @@ merge(Compressor.prototype, {
             var prop = self.properties[i];
             var key = prop.key;
             if (key instanceof AST_Node) key = key.evaluate(compressor);
-            if (typeof key != "string" || /[0-9]+/.test(key)) break;
+            if (is_integer(key)) break;
             if (key !== prop.key) prop.key = "" + key;
         }
         var keys = new Dictionary();
index b7a6f75..01818dc 100644 (file)
@@ -369,3 +369,33 @@ unused_var_side_effects: {
     expect_stdout: "PASS"
     node_version: ">=8"
 }
+
+issue_4329: {
+    options = {
+        properties: true,
+    }
+    input: {
+        console.log({
+            ...{
+                get 0() {
+                    return "FAIL";
+                },
+                ...{
+                    0: "PASS",
+                },
+            },
+        }[0]);
+    }
+    expect: {
+        console.log({
+            ...{
+                get 0() {
+                    return "FAIL";
+                },
+                [0]: "PASS",
+            },
+        }[0]);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=8"
+}