fix corner case in `unused` (#3499)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 18 Oct 2019 12:08:05 +0000 (20:08 +0800)
committerGitHub <noreply@github.com>
Fri, 18 Oct 2019 12:08:05 +0000 (20:08 +0800)
fixes #3497

lib/compress.js
test/compress/drop-unused.js

index 33b62da..0888c10 100644 (file)
@@ -2303,7 +2303,14 @@ merge(Compressor.prototype, {
             return true;
         });
         def(AST_Binary, function(compressor) {
-            return lazy_op[this.operator] && (this.left._dot_throw(compressor) || this.right._dot_throw(compressor));
+            switch (this.operator) {
+              case "&&":
+                return this.left._dot_throw(compressor) || this.right._dot_throw(compressor);
+              case "||":
+                return this.right._dot_throw(compressor);
+              default:
+                return false;
+            }
         });
         def(AST_Conditional, function(compressor) {
             return this.consequent._dot_throw(compressor) || this.alternative._dot_throw(compressor);
@@ -3528,10 +3535,10 @@ merge(Compressor.prototype, {
         var drop_vars = !(self instanceof AST_Toplevel) || compressor.toplevel.vars;
         var assign_as_unused = /keep_assign/.test(compressor.option("unused")) ? return_false : function(node, props) {
             var sym;
-            if (node instanceof AST_Assign && (node.write_only || node.operator == "=")) {
-                sym = node.left;
-            } else if (node instanceof AST_Unary && node.write_only) {
-                sym = node.expression;
+            if (node instanceof AST_Assign) {
+                if (node.write_only || node.operator == "=") sym = node.left;
+            } else if (node instanceof AST_Unary) {
+                if (node.write_only) sym = node.expression;
             }
             if (!/strict/.test(compressor.option("pure_getters"))) return sym instanceof AST_SymbolRef && sym;
             while (sym instanceof AST_PropAccess && !sym.expression.may_throw_on_access(compressor)) {
@@ -3637,7 +3644,7 @@ merge(Compressor.prototype, {
                 if (sym) {
                     var def = sym.definition();
                     var in_use = def.id in in_use_ids;
-                    var value = null;
+                    var value;
                     if (node instanceof AST_Assign) {
                         if (!in_use || node.left === sym && def.id in fixed_ids && fixed_ids[def.id] !== node) {
                             value = get_rhs(node);
@@ -3885,6 +3892,7 @@ merge(Compressor.prototype, {
                     prop.walk(tw);
                 });
                 if (node instanceof AST_Assign) {
+                    if (node.write_only === "p" && node.right.may_throw_on_access(compressor)) return;
                     var right = get_rhs(node);
                     right.walk(tw);
                     if (node.left === sym) {
@@ -4215,7 +4223,7 @@ merge(Compressor.prototype, {
             if (left instanceof AST_PropAccess) {
                 var expr = left.expression;
                 if (expr instanceof AST_Assign && !expr.may_throw_on_access(compressor)) {
-                    expr.write_only = true;
+                    expr.write_only = "p";
                 }
                 if (compressor.has_directive("use strict") && expr.is_constant()) return this;
             }
index ea7ee02..942762f 100644 (file)
@@ -2081,3 +2081,24 @@ issue_3495: {
     }
     expect_stdout: "undefined"
 }
+
+issue_3497: {
+    options = {
+        pure_getters: "strict",
+        side_effects: true,
+        unused: true,
+    }
+    input: {
+        var a;
+        console.log(function(b) {
+            (b += a).p = 0;
+        }());
+    }
+    expect: {
+        var a;
+        console.log(function(b) {
+            (b += a).p = 0;
+        }());
+    }
+    expect_stdout: "undefined"
+}