improve parenthesis emission (#2196)
authorAlex Lam S.L <alexlamsl@gmail.com>
Sun, 2 Jul 2017 20:17:37 +0000 (04:17 +0800)
committerGitHub <noreply@github.com>
Sun, 2 Jul 2017 20:17:37 +0000 (04:17 +0800)
- eliminate `throw` usages
- suppress extraneous parenthesis
  - `new function() {foo.bar()}.baz`
  - `for (function() { "foo" in bar; };;);`

lib/compress.js
lib/output.js
test/compress/loops.js
test/compress/new.js
test/compress/sequences.js

index db45c56..f0aedf5 100644 (file)
@@ -1201,7 +1201,7 @@ merge(Compressor.prototype, {
                     if (stat instanceof AST_For && !(stat.init instanceof AST_Definitions)) {
                         var abort = false;
                         prev.body.walk(new TreeWalker(function(node) {
-                            if (abort) return true;
+                            if (abort || node instanceof AST_Scope) return true;
                             if (node instanceof AST_Binary && node.operator == "in") {
                                 abort = true;
                                 return true;
index 92c7248..9416583 100644 (file)
@@ -672,14 +672,15 @@ function OutputStream(options) {
             // parens around it too, otherwise the call will be
             // interpreted as passing the arguments to the upper New
             // expression.
-            try {
-                this.walk(new TreeWalker(function(node){
-                    if (node instanceof AST_Call) throw p;
-                }));
-            } catch(ex) {
-                if (ex !== p) throw ex;
-                return true;
-            }
+            var parens = false;
+            this.walk(new TreeWalker(function(node) {
+                if (parens || node instanceof AST_Scope) return true;
+                if (node instanceof AST_Call) {
+                    parens = true;
+                    return true;
+                }
+            }));
+            return parens;
         }
     });
 
@@ -1073,19 +1074,17 @@ function OutputStream(options) {
     });
 
     function parenthesize_for_noin(node, output, noin) {
-        if (!noin) node.print(output);
-        else try {
-            // need to take some precautions here:
-            //    https://github.com/mishoo/UglifyJS2/issues/60
-            node.walk(new TreeWalker(function(node){
-                if (node instanceof AST_Binary && node.operator == "in")
-                    throw output;
-            }));
-            node.print(output);
-        } catch(ex) {
-            if (ex !== output) throw ex;
-            node.print(output, true);
-        }
+        var parens = false;
+        // need to take some precautions here:
+        //    https://github.com/mishoo/UglifyJS2/issues/60
+        if (noin) node.walk(new TreeWalker(function(node) {
+            if (parens || node instanceof AST_Scope) return true;
+            if (node instanceof AST_Binary && node.operator == "in") {
+                parens = true;
+                return true;
+            }
+        }));
+        node.print(output, parens);
     };
 
     DEFPRINT(AST_VarDef, function(self, output){
index 89c7e7e..bac4049 100644 (file)
@@ -436,3 +436,17 @@ do_switch: {
         } while (false);
     }
 }
+
+in_parenthesis_1: {
+    input: {
+        for (("foo" in {});0;);
+    }
+    expect_exact: 'for(("foo"in{});0;);'
+}
+
+in_parenthesis_2: {
+    input: {
+        for ((function(){ "foo" in {}; });0;);
+    }
+    expect_exact: 'for(function(){"foo"in{}};0;);'
+}
index 83da88e..640f201 100644 (file)
@@ -82,3 +82,19 @@ new_with_unary_prefix: {
     }
     expect_exact: 'var bar=(+new Date).toString(32);';
 }
+
+dot_parenthesis_1: {
+    input: {
+        console.log(new (Math.random().constructor) instanceof Number);
+    }
+    expect_exact: "console.log(new(Math.random().constructor)instanceof Number);"
+    expect_stdout: "true"
+}
+
+dot_parenthesis_2: {
+    input: {
+        console.log(typeof new function(){Math.random()}.constructor);
+    }
+    expect_exact: "console.log(typeof new function(){Math.random()}.constructor);"
+    expect_stdout: "function"
+}
index f41b603..5ce24ac 100644 (file)
@@ -176,6 +176,11 @@ for_sequences: {
         // 4
         x = (foo in bar);
         for (y = 5; false;);
+        // 5
+        x = function() {
+            foo in bar;
+        };
+        for (y = 5; false;);
     }
     expect: {
         // 1
@@ -188,6 +193,10 @@ for_sequences: {
         // 4
         x = (foo in bar);
         for (y = 5; false;);
+        // 5
+        for (x = function() {
+            foo in bar;
+        }, y = 5; false;);
     }
 }