fix corner case in `join_vars` (#3224)
authorAlex Lam S.L <alexlamsl@gmail.com>
Fri, 27 Jul 2018 11:34:44 +0000 (19:34 +0800)
committerGitHub <noreply@github.com>
Fri, 27 Jul 2018 11:34:44 +0000 (19:34 +0800)
lib/compress.js
test/compress/properties.js

index ca868a9..4675b1c 100644 (file)
@@ -2000,7 +2000,7 @@ merge(Compressor.prototype, {
             statements.length = n;
         }
 
-        function join_object_assignments(defn, body) {
+        function join_assigns(defn, body) {
             var exprs;
             if (body instanceof AST_Assign) {
                 exprs = [ body ];
@@ -2010,7 +2010,7 @@ merge(Compressor.prototype, {
             if (!exprs) return;
             if (defn instanceof AST_Definitions) {
                 var def = defn.definitions[defn.definitions.length - 1];
-                if (trim_object_assignments(def.name, def.value, exprs)) return exprs;
+                if (trim_assigns(def.name, def.value, exprs)) return exprs;
             }
             for (var i = exprs.length - 1; --i >= 0;) {
                 var expr = exprs[i];
@@ -2018,12 +2018,12 @@ merge(Compressor.prototype, {
                 if (expr.operator != "=") continue;
                 if (!(expr.left instanceof AST_SymbolRef)) continue;
                 var tail = exprs.slice(i + 1);
-                if (!trim_object_assignments(expr.left, expr.right, tail)) continue;
+                if (!trim_assigns(expr.left, expr.right, tail)) continue;
                 return exprs.slice(0, i + 1).concat(tail);
             }
         }
 
-        function trim_object_assignments(name, value, exprs) {
+        function trim_assigns(name, value, exprs) {
             if (!(value instanceof AST_Object)) return;
             var trimmed = false;
             do {
@@ -2074,9 +2074,9 @@ merge(Compressor.prototype, {
                         defs = stat;
                     }
                 } else if (stat instanceof AST_Exit) {
-                    stat.value = extract_object_assignments(stat.value);
+                    stat.value = join_assigns_expr(stat.value);
                 } else if (stat instanceof AST_For) {
-                    var exprs = join_object_assignments(prev, stat.init);
+                    var exprs = join_assigns(prev, stat.init);
                     if (exprs) {
                         CHANGED = true;
                         stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
@@ -2097,11 +2097,11 @@ merge(Compressor.prototype, {
                         statements[++j] = stat;
                     }
                 } else if (stat instanceof AST_ForIn) {
-                    stat.object = extract_object_assignments(stat.object);
+                    stat.object = join_assigns_expr(stat.object);
                 } else if (stat instanceof AST_If) {
-                    stat.condition = extract_object_assignments(stat.condition);
+                    stat.condition = join_assigns_expr(stat.condition);
                 } else if (stat instanceof AST_SimpleStatement) {
-                    var exprs = join_object_assignments(prev, stat.body);
+                    var exprs = join_assigns(prev, stat.body);
                     if (exprs) {
                         CHANGED = true;
                         if (!exprs.length) continue;
@@ -2109,29 +2109,23 @@ merge(Compressor.prototype, {
                     }
                     statements[++j] = stat;
                 } else if (stat instanceof AST_Switch) {
-                    stat.expression = extract_object_assignments(stat.expression);
+                    stat.expression = join_assigns_expr(stat.expression);
                 } else if (stat instanceof AST_With) {
-                    stat.expression = extract_object_assignments(stat.expression);
+                    stat.expression = join_assigns_expr(stat.expression);
                 } else {
                     statements[++j] = stat;
                 }
             }
             statements.length = j + 1;
 
-            function extract_object_assignments(value) {
+            function join_assigns_expr(value) {
                 statements[++j] = stat;
-                var exprs = join_object_assignments(prev, value);
-                if (exprs) {
-                    CHANGED = true;
-                    if (exprs.length) {
-                        return make_sequence(value, exprs);
-                    } else if (value instanceof AST_Sequence) {
-                        return value.tail_node().left;
-                    } else {
-                        return value.left;
-                    }
-                }
-                return value;
+                var exprs = join_assigns(prev, value);
+                if (!exprs) return value;
+                CHANGED = true;
+                var tail = value.tail_node();
+                if (exprs[exprs.length - 1] !== tail) exprs.push(tail.left);
+                return make_sequence(value, exprs);
             }
         }
     }
index d36ae07..3a78d62 100644 (file)
@@ -1832,3 +1832,33 @@ issue_3188_3: {
     }
     expect_stdout: "PASS"
 }
+
+join_expr: {
+    options = {
+        evaluate: true,
+        join_vars: true,
+    }
+    input: {
+        var c = "FAIL";
+        (function() {
+            var a = 0;
+            switch ((a = {}) && (a.b = 0)) {
+              case 0:
+                c = "PASS";
+            }
+        })();
+        console.log(c);
+    }
+    expect: {
+        var c = "FAIL";
+        (function() {
+            var a = 0;
+            switch (a = { b: 0 }, a.b) {
+              case 0:
+                c = "PASS";
+            }
+        })();
+        console.log(c);
+    }
+    expect_stdout: "PASS"
+}