fix corner case in `side_effects` (#4752)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 7 Mar 2021 20:19:51 +0000 (20:19 +0000)
committerGitHub <noreply@github.com>
Sun, 7 Mar 2021 20:19:51 +0000 (04:19 +0800)
fixes #4751

lib/compress.js
test/compress/collapse_vars.js
test/compress/evaluate.js
test/compress/ie8.js
test/compress/merge_vars.js
test/compress/pure_getters.js
test/compress/reduce_vars.js
test/compress/sequences.js
test/compress/side_effects.js

index 349dad9..3551655 100644 (file)
@@ -4797,15 +4797,9 @@ merge(Compressor.prototype, {
                 || this.right.has_side_effects(compressor);
         });
         def(AST_Binary, function(compressor) {
-            var lhs = this.left;
-            if (lhs.has_side_effects(compressor)) return true;
-            var rhs = this.right;
-            var op = this.operator;
-            if (!rhs.has_side_effects(compressor)) return op == "in" && !is_object(rhs);
-            if (op == "&&" && rhs instanceof AST_PropAccess && lhs.equivalent_to(rhs.expression)) {
-                return rhs instanceof AST_Sub && rhs.property.has_side_effects(compressor);
-            }
-            return true;
+            return this.left.has_side_effects(compressor)
+                || this.right.has_side_effects(compressor)
+                || this.operator == "in" && !is_object(this.right);
         });
         def(AST_Block, function(compressor) {
             return any(this.body, compressor);
@@ -7220,17 +7214,6 @@ merge(Compressor.prototype, {
             if (!rhs) return left.drop_side_effect_free(compressor, first_in_statement);
             if (lazy_op[op] && rhs.has_side_effects(compressor)) {
                 var node = this;
-                 if (op == "&&"
-                    && rhs instanceof AST_PropAccess
-                    && left.equivalent_to(rhs.expression)
-                    && !left.has_side_effects(compressor)) {
-                    var prop = rhs instanceof AST_Sub
-                        && rhs.property.drop_side_effect_free(compressor, first_in_statement);
-                    if (!prop) return left.drop_side_effect_free(compressor, first_in_statement);
-                    node = node.clone();
-                    node.right = prop;
-                    return node.drop_side_effect_free(compressor, first_in_statement);
-                }
                 if (rhs !== right) {
                     node = node.clone();
                     node.right = rhs.drop_side_effect_free(compressor);
@@ -7242,13 +7225,12 @@ merge(Compressor.prototype, {
                     right: node.right,
                 });
                 return first_in_statement ? best_of_statement(node, negated) : best_of_expression(node, negated);
-            } else {
-                var lhs = left.drop_side_effect_free(compressor, first_in_statement);
-                if (!lhs) return rhs;
-                rhs = rhs.drop_side_effect_free(compressor);
-                if (!rhs) return lhs;
-                return make_sequence(this, [ lhs, rhs ]);
             }
+            var lhs = left.drop_side_effect_free(compressor, first_in_statement);
+            if (!lhs) return rhs;
+            rhs = rhs.drop_side_effect_free(compressor);
+            if (!rhs) return lhs;
+            return make_sequence(this, [ lhs, rhs ]);
         });
         def(AST_Call, function(compressor, first_in_statement) {
             var self = this;
index dcc8739..9719860 100644 (file)
@@ -2862,7 +2862,7 @@ lvalues_def: {
     expect: {
         var a = 0, b = 1;
         a = b++, b = +void 0;
-        a && a++;
+        a && a[a++];
         console.log(a, b);
     }
     expect_stdout: true
@@ -5096,7 +5096,7 @@ issue_2878: {
             }
             b = f2();
             a = 1;
-            b && b[console];
+            b && b.b;
             f2();
         })();
         console.log(c);
@@ -5109,7 +5109,7 @@ issue_2878: {
             }
             b = f2(),
             a = 1,
-            b && console,
+            b && b.b,
             f2();
         })(),
         console.log(c);
@@ -6544,7 +6544,7 @@ issue_3520: {
                 (function f() {
                     c = 0;
                     var i = void 0;
-                    var f = f && f[console && i];
+                    var f = f && f[i];
                 })();
                 a += b;
                 c && b++;
@@ -6558,7 +6558,7 @@ issue_3520: {
             for (var i = 2; --i >= 0;) {
                 (function() {
                     c = 0;
-                    var f = f && f[console && void 0];
+                    var f = f && f[void 0];
                 })();
                 a += b;
                 c && b++;
index 2c978ff..597c7c8 100644 (file)
@@ -2726,8 +2726,8 @@ issue_3944: {
     }
     expect: {
         void function f() {
-            while (b = void 0, b = console.log(0 == (b && b.p)), void 0);
-            var b;
+            while (a = 0 == (a = void 0), console.log(a), void 0);
+            var a;
             f;
         }();
     }
index 7e49672..a1daa59 100644 (file)
@@ -2923,13 +2923,14 @@ issue_4568: {
 issue_4729: {
     options = {
         ie8: true,
+        pure_getters: true,
         toplevel: true,
         unused: true,
     }
     input: {
         try {
             f;
-        } catch(e) {
+        } catch (e) {
             var a = a && a[function f() {}];
             console.log("PASS");
         }
@@ -2937,7 +2938,7 @@ issue_4729: {
     expect: {
         try {
             f;
-        } catch(e) {
+        } catch (e) {
             (function f() {});
             console.log("PASS");
         }
index 667cacf..c45f835 100644 (file)
@@ -2723,7 +2723,7 @@ issue_4135: {
             var c = function() {
                 var d = 0;
                 function f() {
-                    d && d[console];
+                    d && d.p;
                 }
                 f();
                 this;
@@ -2735,7 +2735,7 @@ issue_4135: {
         0;
         a++;
         if (!a)
-            c = (a++, c = 0, void (c && console));
+            c = (a++, c = 0, void (c && c.p));
         var c;
         console.log(a, -1, c);
     }
index 6adc616..13f9d4f 100644 (file)
@@ -1220,6 +1220,104 @@ drop_arguments: {
     expect_stdout: "PASS"
 }
 
+lvalues_def: {
+    options = {
+        collapse_vars: true,
+        pure_getters: true,
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        var a = 0, b = 1;
+        var a = b++, b = +function() {}();
+        a && a[a++];
+        console.log(a, b);
+    }
+    expect: {
+        var a = 0, b = 1;
+        a = b++, b = +void 0;
+        a && a++;
+        console.log(a, b);
+    }
+    expect_stdout: true
+}
+
+side_effects_assign: {
+    options = {
+        evaluate: true,
+        pure_getters: true,
+        reduce_funcs: true,
+        reduce_vars: true,
+        sequences: true,
+        side_effects: true,
+        toplevel: true,
+    }
+    input: {
+        var a = typeof void (a && a.in == 1, 0);
+        console.log(a);
+    }
+    expect: {
+        var a = "undefined";
+        console.log(a);
+    }
+    expect_stdout: "undefined"
+}
+
+issue_2062: {
+    options = {
+        booleans: true,
+        collapse_vars: true,
+        conditionals: true,
+        pure_getters: true,
+        side_effects: true,
+    }
+    input: {
+        var a = 1;
+        if ([ a || a++ + a--, a++ + a--, a && a.var ]);
+        console.log(a);
+    }
+    expect: {
+        var a = 1;
+        a || (a++, a--), a++, a--;
+        console.log(a);
+    }
+    expect_stdout: "1"
+}
+
+issue_2878: {
+    options = {
+        collapse_vars: true,
+        pure_getters: true,
+        sequences: true,
+    }
+    input: {
+        var c = 0;
+        (function(a, b) {
+            function f2() {
+                if (a) c++;
+            }
+            b = f2();
+            a = 1;
+            b && b.b;
+            f2();
+        })();
+        console.log(c);
+    }
+    expect: {
+        var c = 0;
+        (function(a, b) {
+            function f2() {
+                if (a) c++;
+            }
+            b = f2(),
+            a = 1,
+            f2();
+        })(),
+        console.log(c);
+    }
+    expect_stdout: "1"
+}
+
 issue_3427: {
     options = {
         assignments: true,
@@ -1242,6 +1340,74 @@ issue_3427: {
     expect_stdout: true
 }
 
+issue_3490_1: {
+    options = {
+        conditionals: true,
+        dead_code: true,
+        inline: true,
+        pure_getters: true,
+        sequences: true,
+        side_effects: true,
+        toplevel: true,
+    }
+    input: {
+        var b = 42, c = "FAIL";
+        if ({
+            3: function() {
+                var a;
+                return (a && a.p) < this;
+            }(),
+        }) c = "PASS";
+        if (b) while ("" == typeof d);
+        console.log(c, b);
+    }
+    expect: {
+        var b = 42, c = "FAIL";
+        if (function() {
+            var a;
+        }(), c = "PASS", b) while ("" == typeof d);
+        console.log(c, b);
+    }
+    expect_stdout: "PASS 42"
+}
+
+issue_4135: {
+    options = {
+        evaluate: true,
+        inline: true,
+        merge_vars: true,
+        pure_getters: true,
+        reduce_vars: true,
+        side_effects: true,
+        toplevel: true,
+        unused: true,
+    }
+    input: {
+        var a = 0, b = 0;
+        --b;
+        a++;
+        if (!a)
+            var c = function() {
+                var d = 0;
+                function f() {
+                    d && d.p;
+                }
+                f();
+                this;
+            }(a++);
+        console.log(a, b, c);
+    }
+    expect: {
+        var a = 0;
+        0;
+        a++;
+        if (!a)
+            var c = void a++;
+        console.log(a, -1, c);
+    }
+    expect_stdout: "1 -1 undefined"
+}
+
 issue_4440: {
     options = {
         pure_getters: "strict",
@@ -1270,3 +1436,57 @@ issue_4440: {
     }
     expect_stdout: "PASS"
 }
+
+issue_4730_1: {
+    options = {
+        pure_getters: true,
+        side_effects: true,
+    }
+    input: {
+        var a;
+        console.log("PASS") + (a && a[a.p]);
+    }
+    expect: {
+        var a;
+        console.log("PASS");
+    }
+    expect_stdout: "PASS"
+}
+
+issue_4730_2: {
+    options = {
+        pure_getters: true,
+        side_effects: true,
+    }
+    input: {
+        var a;
+        !console.log("PASS") || a && a[a.p];
+    }
+    expect: {
+        var a;
+        console.log("PASS");
+    }
+    expect_stdout: "PASS"
+}
+
+issue_4751: {
+    options = {
+        pure_getters: true,
+        side_effects: true,
+    }
+    input: {
+        var o = {
+            get p() {
+                console.log("PASS");
+            },
+        };
+        o && o.p;
+    }
+    expect: {
+        var o = {
+            get p() {
+                console.log("PASS");
+            },
+        };
+    }
+}
index 110f046..5ae0884 100644 (file)
@@ -2554,7 +2554,7 @@ side_effects_assign: {
         console.log(a);
     }
     expect: {
-        var a = "undefined";
+        var a = typeof void (a && a.in);
         console.log(a);
     }
     expect_stdout: "undefined"
@@ -2595,7 +2595,9 @@ pure_getters_2: {
         var a;
         var a = a && a.b;
     }
-    expect: {}
+    expect: {
+        var a = a && a.b;
+    }
 }
 
 pure_getters_3: {
index 79b308b..90de197 100644 (file)
@@ -754,12 +754,12 @@ issue_2062: {
     }
     input: {
         var a = 1;
-        if ([ a || a++ + a--, a++ + a--, a && a[console] ]);
+        if ([ a || a++ + a--, a++ + a--, a && a.var ]);
         console.log(a);
     }
     expect: {
         var a = 1;
-        a || (a++, a--), a++, --a && console;
+        a || (a++, a--), a++, --a && a.var;
         console.log(a);
     }
     expect_stdout: "1"
@@ -1097,7 +1097,7 @@ issue_3490_1: {
         if ({
             3: function() {
                 var a;
-                return (a && a[console]) < this;
+                return (a && a.p) < this;
             }(),
         }) c = "PASS";
         if (b) while ("" == typeof d);
@@ -1107,7 +1107,7 @@ issue_3490_1: {
         var b = 42, c = "FAIL";
         if (function() {
             var a;
-            a && console;
+            a && a.p;
         }(), c = "PASS", b) while ("" == typeof d);
         console.log(c, b);
     }
index 0329827..0e6a744 100644 (file)
@@ -561,6 +561,7 @@ drop_side_effect_free_call: {
 
 issue_4730_1: {
     options = {
+        pure_getters: "strict",
         side_effects: true,
     }
     input: {
@@ -569,13 +570,15 @@ issue_4730_1: {
     }
     expect: {
         var a;
-        console.log("PASS");
+        console.log("PASS"),
+        a && a[a.p];
     }
     expect_stdout: "PASS"
 }
 
 issue_4730_2: {
     options = {
+        pure_getters: "strict",
         side_effects: true,
     }
     input: {
@@ -584,7 +587,31 @@ issue_4730_2: {
     }
     expect: {
         var a;
-        console.log("PASS");
+        !console.log("PASS") || a && a[a.p];
+    }
+    expect_stdout: "PASS"
+}
+
+issue_4751: {
+    options = {
+        pure_getters: "strict",
+        side_effects: true,
+    }
+    input: {
+        var o = {
+            get p() {
+                console.log("PASS");
+            },
+        };
+        o && o.p;
+    }
+    expect: {
+        var o = {
+            get p() {
+                console.log("PASS");
+            },
+        };
+        o && o.p;
     }
     expect_stdout: "PASS"
 }