fix corner case in `hoist_props` (#3412)
authorAlex Lam S.L <alexlamsl@gmail.com>
Tue, 14 May 2019 11:12:00 +0000 (19:12 +0800)
committerGitHub <noreply@github.com>
Tue, 14 May 2019 11:12:00 +0000 (19:12 +0800)
fixes #3411

lib/compress.js
test/compress/hoist_props.js

index 71f2eae..3bb6cb2 100644 (file)
@@ -519,7 +519,7 @@ merge(Compressor.prototype, {
             if (parent instanceof AST_Call && node === parent.expression) return;
             if (parent instanceof AST_Sequence && node !== parent.tail_node()) return;
             if (parent instanceof AST_SimpleStatement) return;
-            if (parent instanceof AST_Unary) return;
+            if (parent instanceof AST_Unary && !unary_side_effects[parent.operator]) return;
             d.direct_access = true;
         }
 
@@ -4067,6 +4067,16 @@ merge(Compressor.prototype, {
                 }));
                 return make_sequence(node, assignments);
             }
+            if (node instanceof AST_Unary
+                && !unary_side_effects[node.operator]
+                && node.expression instanceof AST_SymbolRef
+                && node.expression.definition().id in defs_by_id) {
+                node = node.clone();
+                node.expression = make_node(AST_Object, node, {
+                    properties: []
+                });
+                return node;
+            }
             if (node instanceof AST_VarDef && can_hoist(node.name, node.value, 0)) {
                 descend(node, this);
                 var defs = new Dictionary();
index 6f30956..b055ae7 100644 (file)
@@ -862,3 +862,27 @@ issue_3071_3: {
     }
     expect_stdout: "2"
 }
+
+issue_3411: {
+    options = {
+        hoist_props: true,
+        reduce_vars: true,
+    }
+    input: {
+        var c = 1;
+        !function f() {
+            var o = {
+                p: --c && f()
+            };
+            +o || console.log("PASS");
+        }();
+    }
+    expect: {
+        var c = 1;
+        !function f() {
+            var o_p = --c && f();
+            +{} || console.log("PASS");
+        }();
+    }
+    expect_stdout: "PASS"
+}