Skip to content

Commit

Permalink
Disallow await before exponential (#12441)
Browse files Browse the repository at this point in the history
* refactor: move unary exponential check to parseMaybeUnary

* fix: disallow await before exponential

* add test cases
  • Loading branch information
JLHwung committed Mar 25, 2021
1 parent 2ae19d0 commit 0067fd9
Show file tree
Hide file tree
Showing 18 changed files with 501 additions and 16 deletions.
34 changes: 19 additions & 15 deletions packages/babel-parser/src/parser/expression.js
Expand Up @@ -399,17 +399,6 @@ export default class ExpressionParser extends LValParser {
const node = this.startNodeAt(leftStartPos, leftStartLoc);
node.left = left;
node.operator = this.state.value;
if (
op === tt.exponent &&
left.type === "UnaryExpression" &&
(this.options.createParenthesizedExpressions ||
!(left.extra && left.extra.parenthesized))
) {
this.raise(
left.argument.start,
Errors.UnexpectedTokenUnaryExponentiation,
);
}

const logical = op === tt.logicalOR || op === tt.logicalAND;
const coalesce = op === tt.nullishCoalescing;
Expand Down Expand Up @@ -506,16 +495,30 @@ export default class ExpressionParser extends LValParser {
);
}

checkExponentialAfterUnary(node: N.AwaitExpression | N.UnaryExpression) {
if (this.match(tt.exponent)) {
this.raise(
node.argument.start,
Errors.UnexpectedTokenUnaryExponentiation,
);
}
}

// Parse unary operators, both prefix and postfix.
// https://tc39.es/ecma262/#prod-UnaryExpression
parseMaybeUnary(refExpressionErrors: ?ExpressionErrors): N.Expression {
parseMaybeUnary(
refExpressionErrors: ?ExpressionErrors,
sawUnary?: boolean,
): N.Expression {
const startPos = this.state.start;
const startLoc = this.state.startLoc;
const isAwait = this.isContextual("await");

if (isAwait && this.isAwaitAllowed()) {
this.next();
return this.parseAwait(startPos, startLoc);
const expr = this.parseAwait(startPos, startLoc);
if (!sawUnary) this.checkExponentialAfterUnary(expr);
return expr;
}
if (
this.isContextual("module") &&
Expand All @@ -536,7 +539,7 @@ export default class ExpressionParser extends LValParser {
const isDelete = this.match(tt._delete);
this.next();

node.argument = this.parseMaybeUnary();
node.argument = this.parseMaybeUnary(null, true);

this.checkExpressionErrors(refExpressionErrors, true);

Expand All @@ -551,6 +554,7 @@ export default class ExpressionParser extends LValParser {
}

if (!update) {
if (!sawUnary) this.checkExponentialAfterUnary(node);
return this.finishNode(node, "UnaryExpression");
}
}
Expand Down Expand Up @@ -2412,7 +2416,7 @@ export default class ExpressionParser extends LValParser {
}

if (!this.state.soloAwait) {
node.argument = this.parseMaybeUnary();
node.argument = this.parseMaybeUnary(null, true);
}

return this.finishNode(node, "AwaitExpression");
Expand Down
2 changes: 1 addition & 1 deletion packages/babel-parser/src/types.js
Expand Up @@ -391,7 +391,7 @@ export type YieldExpression = NodeBase & {

export type AwaitExpression = NodeBase & {
type: "AwaitExpression",
argument: ?Expression,
argument: Expression,
};

export type ArrayExpression = NodeBase & {
Expand Down
@@ -0,0 +1 @@
async () => (await 5) ** 6;
@@ -0,0 +1,56 @@
{
"type": "File",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"program": {
"type": "Program",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"expression": {
"type": "ArrowFunctionExpression",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
"id": null,
"generator": false,
"async": true,
"params": [],
"body": {
"type": "BinaryExpression",
"start":12,"end":26,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":26}},
"left": {
"type": "ParenthesizedExpression",
"start":12,"end":21,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":21}},
"expression": {
"type": "AwaitExpression",
"start":13,"end":20,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":20}},
"argument": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20}},
"extra": {
"rawValue": 5,
"raw": "5"
},
"value": 5
}
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":25,"end":26,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":26}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
}
],
"directives": []
}
}
@@ -0,0 +1 @@
async () => await 5 ** 6;
@@ -0,0 +1,55 @@
{
"type": "File",
"start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},
"errors": [
"SyntaxError: Illegal expression. Wrap left hand side or entire exponentiation in parentheses. (1:18)"
],
"program": {
"type": "Program",
"start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},
"expression": {
"type": "ArrowFunctionExpression",
"start":0,"end":24,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":24}},
"id": null,
"generator": false,
"async": true,
"params": [],
"body": {
"type": "BinaryExpression",
"start":12,"end":24,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":24}},
"left": {
"type": "AwaitExpression",
"start":12,"end":19,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":19}},
"argument": {
"type": "NumericLiteral",
"start":18,"end":19,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":19}},
"extra": {
"rawValue": 5,
"raw": "5"
},
"value": 5
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":23,"end":24,"loc":{"start":{"line":1,"column":23},"end":{"line":1,"column":24}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
}
],
"directives": []
}
}
@@ -0,0 +1 @@
async () => await -5 ** 6;
@@ -0,0 +1,61 @@
{
"type": "File",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
"errors": [
"SyntaxError: Illegal expression. Wrap left hand side or entire exponentiation in parentheses. (1:18)"
],
"program": {
"type": "Program",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
"expression": {
"type": "ArrowFunctionExpression",
"start":0,"end":25,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":25}},
"id": null,
"generator": false,
"async": true,
"params": [],
"body": {
"type": "BinaryExpression",
"start":12,"end":25,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":25}},
"left": {
"type": "AwaitExpression",
"start":12,"end":20,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":20}},
"argument": {
"type": "UnaryExpression",
"start":18,"end":20,"loc":{"start":{"line":1,"column":18},"end":{"line":1,"column":20}},
"operator": "-",
"prefix": true,
"argument": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20}},
"extra": {
"rawValue": 5,
"raw": "5"
},
"value": 5
}
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":24,"end":25,"loc":{"start":{"line":1,"column":24},"end":{"line":1,"column":25}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
}
],
"directives": []
}
}
@@ -0,0 +1 @@
(-+5 ** 6);
@@ -0,0 +1,59 @@
{
"type": "File",
"start":0,"end":11,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"errors": [
"SyntaxError: Illegal expression. Wrap left hand side or entire exponentiation in parentheses. (1:2)"
],
"program": {
"type": "Program",
"start":0,"end":11,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":11,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":11}},
"expression": {
"type": "BinaryExpression",
"start":1,"end":9,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":9}},
"extra": {
"parenthesized": true,
"parenStart": 0
},
"left": {
"type": "UnaryExpression",
"start":1,"end":4,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":4}},
"operator": "-",
"prefix": true,
"argument": {
"type": "UnaryExpression",
"start":2,"end":4,"loc":{"start":{"line":1,"column":2},"end":{"line":1,"column":4}},
"operator": "+",
"prefix": true,
"argument": {
"type": "NumericLiteral",
"start":3,"end":4,"loc":{"start":{"line":1,"column":3},"end":{"line":1,"column":4}},
"extra": {
"rawValue": 5,
"raw": "5"
},
"value": 5
}
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":8,"end":9,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":9}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
],
"directives": []
}
}
@@ -0,0 +1 @@
async () => (await 5) ** 6;
@@ -0,0 +1,56 @@
{
"type": "File",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"program": {
"type": "Program",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"sourceType": "script",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"expression": {
"type": "ArrowFunctionExpression",
"start":0,"end":26,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":26}},
"id": null,
"generator": false,
"async": true,
"params": [],
"body": {
"type": "BinaryExpression",
"start":12,"end":26,"loc":{"start":{"line":1,"column":12},"end":{"line":1,"column":26}},
"left": {
"type": "AwaitExpression",
"start":13,"end":20,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":20}},
"extra": {
"parenthesized": true,
"parenStart": 12
},
"argument": {
"type": "NumericLiteral",
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20}},
"extra": {
"rawValue": 5,
"raw": "5"
},
"value": 5
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":25,"end":26,"loc":{"start":{"line":1,"column":25},"end":{"line":1,"column":26}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
}
],
"directives": []
}
}
@@ -0,0 +1 @@
async (a) => await a! ** 6;

0 comments on commit 0067fd9

Please sign in to comment.