Disallow await before exponential (#12441)

* refactor: move unary exponential check to parseMaybeUnary

* fix: disallow await before exponential

* add test cases
This commit is contained in:
Huáng Jùnliàng 2021-03-25 11:20:47 -04:00 committed by GitHub
parent 2ae19d01b1
commit 0067fd9e02
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 501 additions and 16 deletions

View File

@ -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;
@ -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") &&
@ -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);
@ -551,6 +554,7 @@ export default class ExpressionParser extends LValParser {
}
if (!update) {
if (!sawUnary) this.checkExponentialAfterUnary(node);
return this.finishNode(node, "UnaryExpression");
}
}
@ -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");

View File

@ -391,7 +391,7 @@ export type YieldExpression = NodeBase & {
export type AwaitExpression = NodeBase & {
type: "AwaitExpression",
argument: ?Expression,
argument: Expression,
};
export type ArrayExpression = NodeBase & {

View File

@ -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": []
}
}

View File

@ -0,0 +1 @@
async () => await 5 ** 6;

View File

@ -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": []
}
}

View File

@ -0,0 +1 @@
async () => await -5 ** 6;

View File

@ -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": []
}
}

View File

@ -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": []
}
}

View File

@ -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": []
}
}

View File

@ -0,0 +1 @@
async (a) => await a! ** 6;

View File

@ -0,0 +1,61 @@
{
"type": "File",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"errors": [
"SyntaxError: Illegal expression. Wrap left hand side or entire exponentiation in parentheses. (1:19)"
],
"program": {
"type": "Program",
"start":0,"end":27,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":27}},
"sourceType": "module",
"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": [
{
"type": "Identifier",
"start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"a"},
"name": "a"
}
],
"body": {
"type": "BinaryExpression",
"start":13,"end":26,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":26}},
"left": {
"type": "AwaitExpression",
"start":13,"end":21,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":21}},
"argument": {
"type": "TSNonNullExpression",
"start":19,"end":21,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":21}},
"expression": {
"type": "Identifier",
"start":19,"end":20,"loc":{"start":{"line":1,"column":19},"end":{"line":1,"column":20},"identifierName":"a"},
"name": "a"
}
}
},
"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": []
}
}

View File

@ -0,0 +1,63 @@
{
"type": "File",
"start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}},
"errors": [
"SyntaxError: Illegal expression. Wrap left hand side or entire exponentiation in parentheses. (1:8)"
],
"program": {
"type": "Program",
"start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":16,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":16}},
"expression": {
"type": "ArrowFunctionExpression",
"start":0,"end":15,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":15}},
"id": null,
"generator": false,
"async": false,
"params": [
{
"type": "Identifier",
"start":1,"end":2,"loc":{"start":{"line":1,"column":1},"end":{"line":1,"column":2},"identifierName":"a"},
"name": "a"
}
],
"body": {
"type": "BinaryExpression",
"start":7,"end":15,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":15}},
"left": {
"type": "UnaryExpression",
"start":7,"end":10,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":10}},
"operator": "+",
"prefix": true,
"argument": {
"type": "TSNonNullExpression",
"start":8,"end":10,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":10}},
"expression": {
"type": "Identifier",
"start":8,"end":9,"loc":{"start":{"line":1,"column":8},"end":{"line":1,"column":9},"identifierName":"a"},
"name": "a"
}
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":14,"end":15,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":15}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
}
],
"directives": []
}
}

View File

@ -0,0 +1,62 @@
{
"type": "File",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},
"program": {
"type": "Program",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},
"sourceType": "module",
"interpreter": null,
"body": [
{
"type": "ExpressionStatement",
"start":0,"end":29,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":29}},
"expression": {
"type": "ArrowFunctionExpression",
"start":0,"end":28,"loc":{"start":{"line":1,"column":0},"end":{"line":1,"column":28}},
"id": null,
"generator": false,
"async": true,
"params": [
{
"type": "Identifier",
"start":7,"end":8,"loc":{"start":{"line":1,"column":7},"end":{"line":1,"column":8},"identifierName":"a"},
"name": "a"
}
],
"body": {
"type": "BinaryExpression",
"start":13,"end":28,"loc":{"start":{"line":1,"column":13},"end":{"line":1,"column":28}},
"left": {
"type": "AwaitExpression",
"start":14,"end":22,"loc":{"start":{"line":1,"column":14},"end":{"line":1,"column":22}},
"extra": {
"parenthesized": true,
"parenStart": 13
},
"argument": {
"type": "TSNonNullExpression",
"start":20,"end":22,"loc":{"start":{"line":1,"column":20},"end":{"line":1,"column":22}},
"expression": {
"type": "Identifier",
"start":20,"end":21,"loc":{"start":{"line":1,"column":20},"end":{"line":1,"column":21},"identifierName":"a"},
"name": "a"
}
}
},
"operator": "**",
"right": {
"type": "NumericLiteral",
"start":27,"end":28,"loc":{"start":{"line":1,"column":27},"end":{"line":1,"column":28}},
"extra": {
"rawValue": 6,
"raw": "6"
},
"value": 6
}
}
}
}
],
"directives": []
}
}