fix corner case in `evaluate` (#3998)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 14 Jun 2020 17:28:44 +0000 (01:28 +0800)
committerGitHub <noreply@github.com>
Sun, 14 Jun 2020 17:28:44 +0000 (01:28 +0800)
fixes #3997

lib/compress.js
test/compress/evaluate.js

index cf28618..b312c64 100644 (file)
@@ -3295,11 +3295,8 @@ merge(Compressor.prototype, {
             if (node instanceof AST_Unary && unary_arithmetic[node.operator]) modified(node.expression);
         });
         function modified(node) {
-            if (node instanceof AST_Dot) {
-                modified(node.expression);
-            } else if (node instanceof AST_Sub) {
+            if (node instanceof AST_PropAccess) {
                 modified(node.expression);
-                node.property.walk(scan_modified);
             } else if (node instanceof AST_SymbolRef) {
                 node.definition().references.forEach(function(ref) {
                     delete ref._eval;
@@ -3329,14 +3326,17 @@ merge(Compressor.prototype, {
             }
             var op = this.operator;
             var node;
-            if (HOP(lhs, "_eval") || !(lhs instanceof AST_SymbolRef) || !lhs.fixed || !lhs.definition().fixed) {
-                node = op == "=" ? this.right : make_node(AST_Binary, this, {
+            if (!HOP(lhs, "_eval") && lhs instanceof AST_SymbolRef && lhs.fixed && lhs.definition().fixed) {
+                node = lhs;
+            } else if (op == "=") {
+                lhs.walk(scan_modified);
+                node = this.right;
+            } else {
+                node = make_node(AST_Binary, this, {
                     operator: op.slice(0, -1),
                     left: lhs,
                     right: this.right,
                 });
-            } else {
-                node = lhs;
             }
             var value = node._eval(compressor, ignore_side_effects, cached, depth);
             if (value === node) return this;
index 4fecd70..dd94f61 100644 (file)
@@ -2812,3 +2812,24 @@ operator_in: {
         "true",
     ]
 }
+
+issue_3997: {
+    options = {
+        evaluate: true,
+        reduce_vars: true,
+        toplevel: true,
+    }
+    input: {
+        var a = function f(b) {
+            return b[b += this] = b;
+        }(0);
+        console.log(typeof a);
+    }
+    expect: {
+        var a = function f(b) {
+            return b[b += this] = b;
+        }(0);
+        console.log(typeof a);
+    }
+    expect_stdout: "string"
+}