don't move expressions containing the binary `in` operator into the `for` initializer
authorMihai Bazon <mihai@bazon.net>
Tue, 30 Oct 2012 12:50:47 +0000 (14:50 +0200)
committerMihai Bazon <mihai@bazon.net>
Tue, 30 Oct 2012 12:50:47 +0000 (14:50 +0200)
(opera can't parse it)

close #25

lib/compress.js
test/compress/sequences.js

index 2ea91d0..ee255d7 100644 (file)
@@ -427,12 +427,23 @@ merge(Compressor.prototype, {
             var ret = [], prev = null;
             statements.forEach(function(stat){
                 if (prev) {
-                    if (stat instanceof AST_For && stat.init && !(stat.init instanceof AST_Definitions)) {
-                        stat.init = cons_seq(stat.init);
-                    }
-                    else if (stat instanceof AST_For && !stat.init) {
-                        stat.init = prev.body;
-                        ret.pop();
+                    if (stat instanceof AST_For) {
+                        var opera = {};
+                        try {
+                            prev.body.walk(new TreeWalker(function(node){
+                                if (node instanceof AST_Binary && node.operator == "in")
+                                    throw opera;
+                            }));
+                            if (stat.init && !(stat.init instanceof AST_Definitions)) {
+                                stat.init = cons_seq(stat.init);
+                            }
+                            else if (!stat.init) {
+                                stat.init = prev.body;
+                                ret.pop();
+                            }
+                        } catch(ex) {
+                            if (ex !== opera) throw ex;
+                        }
                     }
                     else if (stat instanceof AST_If) {
                         stat.condition = cons_seq(stat.condition);
index d48eced..6f63ace 100644 (file)
@@ -127,3 +127,35 @@ lift_sequences_4: {
         x = baz;
     }
 }
+
+for_sequences: {
+    options = { sequences: true };
+    input: {
+        // 1
+        foo();
+        bar();
+        for (; false;);
+        // 2
+        foo();
+        bar();
+        for (x = 5; false;);
+        // 3
+        x = (foo in bar);
+        for (; false;);
+        // 4
+        x = (foo in bar);
+        for (y = 5; false;);
+    }
+    expect: {
+        // 1
+        for (foo(), bar(); false;);
+        // 2
+        for (foo(), bar(), x = 5; false;);
+        // 3
+        x = (foo in bar);
+        for (; false;);
+        // 4
+        x = (foo in bar);
+        for (y = 5; false;);
+    }
+}