Repository: estools/escodegen (JavaScript)

Issue:
omitting parentheses from the argument of an await expression can change its meaning
```javascript
await (q() ? a() : b());
```
This expression needs the parentheses to work as intended. Without them, `await` will wait on `q()`, rather than on `a()` or `b()`.

The AST representing this expression is:

```
const expr = {
  type: 'AwaitExpression',
  argument: {
    type: 'ConditionalExpression',
    test: {
      type: 'CallExpression',
      callee: {
        type: 'Identifier',
        name: 'q'
      },
      arguments: []
    },
    consequent: {
      type: 'CallExpression',
      callee: {
        type: 'Identifier',
        name: 'a'
      },
      arguments: []
    },
    alternate: {
      type: 'CallExpression',
      callee: {
        type: 'Identifier',
        name: 'b'
      },
      arguments: []
    }
  }
};
```

Without the parentheses, the AST is this:
```
{
  type: 'ConditionalExpression',
  test: {
    type: 'AwaitExpression',
    argument: {
      type: 'CallExpression',
      callee: {
        type: 'Identifier',
        name: 'q'
      },
      arguments: []
    }
  },
  consequent: {
    type: 'CallExpression',
    callee: {
      type: 'Identifier',
      name: 'a'
    },
    arguments: []
  },
  alternate: {
    type: 'CallExpression',
    callee: {
      type: 'Identifier',
      name: 'b'
    },
    arguments: []
  }
}
```

The first AST generates code which parses into the second, and these are not equivalent.

### To reproduce
Paste the following code snippet into the tool [here](http://esprima.org/demo/rewrite.html):

```javascript
async function test() {
	await (q() ? a() : b());
}
```

Click rewrite and observe the parentheses have been removed. Going back and forth between AST and code with this snippet will not preserve the semantics of the expression.


Discussion:

Patch:
diff --git a/escodegen.js b/escodegen.js
index 54e7cfab..a8d0170c 100644
--- a/escodegen.js
+++ b/escodegen.js
@@ -82,7 +82,6 @@
     Precedence = {
         Sequence: 0,
         Yield: 1,
-        Await: 1,
         Assignment: 1,
         Conditional: 2,
         ArrowFunction: 2,
@@ -96,6 +95,7 @@
         BitwiseSHIFT: 10,
         Additive: 11,
         Multiplicative: 12,
+        Await: 13,
         Unary: 13,
         Postfix: 14,
         Call: 15,


Test patch:
diff --git a/test/harmony.js b/test/harmony.js
index a57e4848..2dfeaf9e 100644
--- a/test/harmony.js
+++ b/test/harmony.js
@@ -5927,6 +5927,46 @@ data = {
             }
         },
 
+        'async function test() {\n    await (foo ? bar : quux);\n}': {
+            generateFrom: {
+                "type": "FunctionDeclaration",
+                "id": {
+                    "type": "Identifier",
+                    "name": "test"
+                },
+                "params": [],
+                "body": {
+                    "type": "BlockStatement",
+                    "body": [
+                        {
+                            "type": "ExpressionStatement",
+                            "expression": {
+                                "type": "AwaitExpression",
+                                "argument": {
+                                    "type": "ConditionalExpression",
+                                    "test": {
+                                        "type": "Identifier",
+                                        "name": "foo"
+                                    },
+                                    "consequent": {
+                                        "type": "Identifier",
+                                        "name": "bar"
+                                    },
+                                    "alternate": {
+                                        "type": "Identifier",
+                                        "name": "quux"
+                                    }
+                                }
+                            }
+                        }
+                    ]
+                },
+                "generator": false,
+                "expression": false,
+                "async": true
+            }   
+        },
+
         'f(async function (promise) {\n    await promise;\n});': {
             generateFrom: {
                 "type": "ExpressionStatement",