fix corner case in `objects` (#4270)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 9 Nov 2020 02:47:02 +0000 (02:47 +0000)
committerGitHub <noreply@github.com>
Mon, 9 Nov 2020 02:47:02 +0000 (10:47 +0800)
fixes #4269

lib/compress.js
test/compress/objects.js

index 87e26f8..ef775b9 100644 (file)
@@ -9407,13 +9407,16 @@ merge(Compressor.prototype, {
 
     OPT(AST_Object, function(self, compressor) {
         if (!compressor.option("objects") || compressor.has_directive("use strict")) return self;
+        for (var i = self.properties.length; --i >= 0;) {
+            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 (key !== prop.key) prop.key = "" + key;
+        }
         var keys = new Dictionary();
         var values = [];
         self.properties.forEach(function(prop) {
-            if (prop.key instanceof AST_Node) {
-                var key = prop.key.evaluate(compressor);
-                if (key !== prop.key) prop.key = "" + key;
-            }
             if (prop instanceof AST_ObjectKeyVal && typeof prop.key == "string") {
                 if (prop.value.has_side_effects(compressor)) flush();
                 keys.add(prop.key, prop.value);
index 3fb6ec0..51b7bcc 100644 (file)
@@ -256,3 +256,107 @@ keep_computed_key: {
     expect_stdout: "PASS"
     node_version: ">=4"
 }
+
+issue_4269_1: {
+    options = {
+        evaluate: true,
+        objects: 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: ">=4"
+}
+
+issue_4269_2: {
+    options = {
+        evaluate: true,
+        objects: 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: ">=4"
+}
+
+issue_4269_3: {
+    options = {
+        evaluate: true,
+        objects: true,
+    }
+    input: {
+        console.log({
+            ["foo"]: "bar",
+            get 42() {
+                return "FAIL";
+            },
+            42: "PASS",
+        }[42]);
+    }
+    expect: {
+        console.log({
+            ["foo"]: "bar",
+            get 42() {
+                return "FAIL";
+            },
+            42: "PASS",
+        }[42]);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=4"
+}
+
+issue_4269_4: {
+    options = {
+        evaluate: true,
+        objects: true,
+    }
+    input: {
+        console.log({
+            get 42() {
+                return "FAIL";
+            },
+            ["foo"]: "bar",
+            42: "PASS",
+        }[42]);
+    }
+    expect: {
+        console.log({
+            get 42() {
+                return "FAIL";
+            },
+            ["foo"]: "bar",
+            42: "PASS",
+        }[42]);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=4"
+}