fix & extend `join_vars` for object assigments (#2781)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 14 Jan 2018 09:11:31 +0000 (17:11 +0800)
committerGitHub <noreply@github.com>
Sun, 14 Jan 2018 09:11:31 +0000 (17:11 +0800)
lib/compress.js
test/compress/properties.js

index b35e453..321a134 100644 (file)
@@ -1712,6 +1712,7 @@ merge(Compressor.prototype, {
             do {
                 var node = exprs[0];
                 if (!(node instanceof AST_Assign)) break;
+                if (node.operator != "=") break;
                 if (!(node.left instanceof AST_PropAccess)) break;
                 var sym = node.left.expression;
                 if (!(sym instanceof AST_SymbolRef)) break;
@@ -1748,8 +1749,26 @@ merge(Compressor.prototype, {
                         statements[++j] = stat;
                         defs = stat;
                     }
+                } else if (stat instanceof AST_Exit) {
+                    var exprs = join_object_assignments(prev, stat.value);
+                    if (exprs) {
+                        CHANGED = true;
+                        if (exprs.length) {
+                            stat.value = make_sequence(stat.value, exprs);
+                        } else if (stat.value instanceof AST_Sequence) {
+                            stat.value = stat.value.tail_node().left;
+                        } else {
+                            stat.value = stat.value.left;
+                        }
+                    }
+                    statements[++j] = stat;
                 } else if (stat instanceof AST_For) {
-                    if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) {
+                    var exprs = join_object_assignments(prev, stat.init);
+                    if (exprs) {
+                        CHANGED = true;
+                        stat.init = exprs.length ? make_sequence(stat.init, exprs) : null;
+                        statements[++j] = stat;
+                    } else if (prev instanceof AST_Var && (!stat.init || stat.init.TYPE == prev.TYPE)) {
                         if (stat.init) {
                             prev.definitions = prev.definitions.concat(stat.init.definitions);
                         }
index 6b368e6..7df53d3 100644 (file)
@@ -1188,3 +1188,113 @@ join_object_assignments_3: {
     }
     expect_stdout: "PASS"
 }
+
+join_object_assignments_4: {
+    options = {
+        join_vars: true,
+    }
+    input: {
+        console.log(function() {
+            var o = {
+                p: 3
+            };
+            return o.q = "foo";
+        }());
+    }
+    expect: {
+        console.log(function() {
+            var o = {
+                p: 3,
+                q: "foo"
+            };
+            return o.q;
+        }());
+    }
+    expect_stdout: "foo"
+}
+
+join_object_assignments_5: {
+    options = {
+        join_vars: true,
+    }
+    input: {
+        console.log(function() {
+            var o = {
+                p: 3
+            };
+            return o.q = /foo/,
+            o.r = "bar";
+        }());
+    }
+    expect: {
+        console.log(function() {
+            var o = {
+                p: 3,
+                q: /foo/,
+                r: "bar"
+            };
+            return o.r;
+        }());
+    }
+    expect_stdout: "bar"
+}
+
+join_object_assignments_6: {
+    options = {
+        join_vars: true,
+    }
+    input: {
+        console.log(function() {
+            var o = {
+                p: 3
+            };
+            return o.q = "foo",
+            o.p += "",
+            console.log(o.q),
+            o.p;
+        }());
+    }
+    expect: {
+        console.log(function() {
+            var o = {
+                p: 3,
+                q: "foo"
+            };
+            return o.p += "",
+            console.log(o.q),
+            o.p;
+        }());
+    }
+    expect_stdout: [
+        "foo",
+        "3",
+    ]
+}
+
+join_object_assignments_7: {
+    options = {
+        join_vars: true,
+    }
+    input: {
+        console.log(function() {
+            var o = {
+                p: 3
+            };
+            for (o.q = "foo"; console.log(o.q););
+            return o.p;
+        }());
+    }
+    expect: {
+        console.log(function() {
+            for (var o = {
+                p: 3,
+                q: "foo"
+            }; console.log(o.q););
+            return o.p;
+        }());
+    }
+    expect_stdout: [
+        "foo",
+        "3",
+    ]
+}