enhance `side_effects` & `unused` (#5181)
authorAlex Lam S.L <alexlamsl@gmail.com>
Mon, 22 Nov 2021 03:14:28 +0000 (03:14 +0000)
committerGitHub <noreply@github.com>
Mon, 22 Nov 2021 03:14:28 +0000 (11:14 +0800)
lib/compress.js
test/compress/destructured.js
test/compress/pure_getters.js
test/compress/rests.js

index 60f2e26..1f2af1f 100644 (file)
@@ -7208,7 +7208,7 @@ merge(Compressor.prototype, {
                       case 1:
                         if (!drop) break;
                         var sym = elements[0];
-                        if (!(sym instanceof AST_Symbol)) break;
+                        if (sym.has_side_effects(compressor)) break;
                         value = make_node(AST_Sub, node, {
                             expression: value,
                             property: make_node(AST_Number, node, { value: 0 }),
@@ -7334,7 +7334,7 @@ merge(Compressor.prototype, {
                         if (!drop) break;
                         var prop = properties[0];
                         if (prop.key instanceof AST_Node) break;
-                        if (!(prop.value instanceof AST_Symbol)) break;
+                        if (prop.value.has_side_effects(compressor)) break;
                         value = make_node(AST_Sub, node, {
                             expression: value,
                             property: make_node_from_constant(prop.key, prop),
@@ -7809,14 +7809,10 @@ merge(Compressor.prototype, {
                 if (compressor.has_directive("use strict") && expr.is_constant()) return this;
             }
             if (left.has_side_effects(compressor)) return this;
-            var right = this.right;
-            if (!lazy_op[this.operator.slice(0, -1)]) {
-                this.write_only = true;
-                if (root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) {
-                    return right.drop_side_effect_free(compressor);
-                }
-            }
-            return this;
+            if (lazy_op[this.operator.slice(0, -1)]) return this;
+            this.write_only = true;
+            if (!root_expr(left).is_constant_expression(compressor.find_parent(AST_Scope))) return this;
+            return this.right.drop_side_effect_free(compressor);
         });
         def(AST_Await, function(compressor) {
             if (!compressor.option("awaits")) return this;
index 9731f0e..325eef1 100644 (file)
@@ -1581,6 +1581,75 @@ hoist_vars: {
     node_version: ">=6"
 }
 
+singleton_1: {
+    options = {
+        pure_getters: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        var [ a ] = "P", b, o = {};
+        [ { 1: o.p } ] = [ "FAIL" ];
+        ({ foo: [ o.q ] } = { foo: "S" });
+        [ b = "S" ] = [];
+        console.log(a + o.p + o.q + b);
+    }
+    expect: {
+        var b, a = "P"[0], o = {};
+        o.p = [ "FAIL"["1"] ][0];
+        o.q = { foo: "S"[0] }["foo"];
+        [ b = "S" ] = [];
+        console.log(a + o.p + o.q + b);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}
+
+singleton_2: {
+    options = {
+        evaluate: true,
+        passes: 2,
+        pure_getters: true,
+        side_effects: true,
+        unsafe: true,
+        unused: true,
+    }
+    input: {
+        var [ a ] = "P", b, o = {};
+        [ { 1: o.p } ] = [ "FAIL" ];
+        ({ foo: [ o.q ] } = { foo: "S" });
+        [ b = "S" ] = [];
+        console.log(a + o.p + o.q + b);
+    }
+    expect: {
+        var b, a = "P", o = {};
+        o.p = "A";
+        o.q = "S";
+        [ b = "S" ] = [];
+        console.log(a + o.p + o.q + b);
+    }
+    expect_stdout: "PASS"
+    node_version: ">=6"
+}
+
+singleton_side_effects: {
+    options = {
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        [ 42[console.log("foo")] ] = [ console.log("bar") ];
+    }
+    expect: {
+        [ 42[console.log("foo")] ] = [ console.log("bar") ];
+    }
+    expect_stdout: [
+        "bar",
+        "foo",
+    ]
+    node_version: ">=6"
+}
+
 issue_4280: {
     options = {
         evaluate: true,
index ad2117c..0ac1592 100644 (file)
@@ -1640,6 +1640,26 @@ nested_property_assignments_3: {
     expect_stdout: "PASS"
 }
 
+nested_property_assignments_4: {
+    options = {
+        pure_getters: true,
+        side_effects: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var n, o = { p: { q: { r: "PASS" } } };
+        (n = o.p).r = n.q.r;
+        console.log(o.p.r);
+    }
+    expect: {
+        var n, o = { p: { q: { r: "PASS" } } };
+        (n = o.p).r = n.q.r;
+        console.log(o.p.r);
+    }
+    expect_stdout: "PASS"
+}
+
 issue_4939: {
     options = {
         pure_getters: "strict",
index d88ad66..1a557bc 100644 (file)
@@ -1044,13 +1044,13 @@ issue_5100_1: {
     }
     expect: {
         var a;
-        {
+        ({
             p: {},
             ...a
-        } = [ {
+        } = [ {
             p: [ a = 42["q"] ],
             r: "PASS",
-        } ];
+        } ][0]);
         console.log(a.r);
     }
     expect_stdout: "PASS"
@@ -1077,12 +1077,12 @@ issue_5100_2: {
     }
     expect: {
         var a;
-        {
+        ({
             p: {},
             ...a
-        } = [ {
+        } = [ {
             p: [ console.log("PASS"), a = 42["q"] ],
-        } ];
+        } ][0]);
     }
     expect_stdout: "PASS"
     node_version: ">=10"