fix invalid AST produced by dropping unused variable
authorMihai Bazon <mihai@bazon.net>
Mon, 12 Nov 2012 11:23:57 +0000 (13:23 +0200)
committerMihai Bazon <mihai@bazon.net>
Mon, 12 Nov 2012 11:23:57 +0000 (13:23 +0200)
close #44

lib/compress.js
test/compress/issue-44.js [new file with mode: 0644]

index 9400b86..a4a53f5 100644 (file)
@@ -919,7 +919,7 @@ merge(Compressor.prototype, {
             }
             // pass 3: we should drop declarations not in_use
             var tt = new TreeTransformer(
-                function before(node, descend) {
+                function before(node, descend, in_list) {
                     if (node instanceof AST_Lambda) {
                         for (var a = node.argnames, i = a.length; --i >= 0;) {
                             var sym = a[i];
@@ -1010,6 +1010,19 @@ merge(Compressor.prototype, {
                         }
                         return node;
                     }
+                    if (node instanceof AST_For && node.init instanceof AST_BlockStatement) {
+                        descend(node, this);
+                        // certain combination of unused name + side effect leads to:
+                        //    https://github.com/mishoo/UglifyJS2/issues/44
+                        // that's an invalid AST.
+                        // We fix it at this stage by moving the `var` outside the `for`.
+                        var body = node.init.body.slice(0, -1);
+                        node.init = node.init.body.slice(-1)[0].body;
+                        body.push(node);
+                        return in_list ? MAP.splice(body) : make_node(AST_BlockStatement, node, {
+                            body: body
+                        });
+                    }
                     if (node instanceof AST_Scope && node !== self)
                         return node;
                 }
diff --git a/test/compress/issue-44.js b/test/compress/issue-44.js
new file mode 100644 (file)
index 0000000..7a972f9
--- /dev/null
@@ -0,0 +1,31 @@
+issue_44_valid_ast_1: {
+    options = { unused: true };
+    input: {
+        function a(b) {
+            for (var i = 0, e = b.qoo(); ; i++) {}
+        }
+    }
+    expect: {
+        function a(b) {
+            var i = 0;
+            for (b.qoo(); ; i++);
+        }
+    }
+}
+
+issue_44_valid_ast_2: {
+    options = { unused: true };
+    input: {
+        function a(b) {
+            if (foo) for (var i = 0, e = b.qoo(); ; i++) {}
+        }
+    }
+    expect: {
+        function a(b) {
+            if (foo) {
+                var i = 0;
+                for (b.qoo(); ; i++);
+            }
+        }
+    }
+}