fix: async arrow functions should not be allowed after binary… (#11284)
* Forbid async arrow functions after binary operator. This commit makes Babel throw an error when parsing code like "3 + async() => 2". * Make atPossibleAsync more accurate * Change atPossibleAsync to atPossibleAsyncArrow Add an extra test to atPossibleAsync and refactor it to atPossibleAsyncArrow. This also fixes a bug in the Typescript plugin, so a new test has been added. * Add test for async arrow after unary operator
This commit is contained in:
parent
a9b430b464
commit
0e5c1da659
@ -556,7 +556,7 @@ export default class ExpressionParser extends LValParser {
|
|||||||
): N.Expression {
|
): N.Expression {
|
||||||
const state = {
|
const state = {
|
||||||
optionalChainMember: false,
|
optionalChainMember: false,
|
||||||
maybeAsyncArrow: this.atPossibleAsync(base),
|
maybeAsyncArrow: this.atPossibleAsyncArrow(base),
|
||||||
stop: false,
|
stop: false,
|
||||||
};
|
};
|
||||||
do {
|
do {
|
||||||
@ -748,13 +748,15 @@ export default class ExpressionParser extends LValParser {
|
|||||||
return this.finishNode(node, "TaggedTemplateExpression");
|
return this.finishNode(node, "TaggedTemplateExpression");
|
||||||
}
|
}
|
||||||
|
|
||||||
atPossibleAsync(base: N.Expression): boolean {
|
atPossibleAsyncArrow(base: N.Expression): boolean {
|
||||||
return (
|
return (
|
||||||
base.type === "Identifier" &&
|
base.type === "Identifier" &&
|
||||||
base.name === "async" &&
|
base.name === "async" &&
|
||||||
this.state.lastTokEnd === base.end &&
|
this.state.lastTokEnd === base.end &&
|
||||||
!this.canInsertSemicolon() &&
|
!this.canInsertSemicolon() &&
|
||||||
this.input.slice(base.start, base.end) === "async"
|
// check there are no escape sequences, such as \u{61}sync
|
||||||
|
base.end - base.start === 5 &&
|
||||||
|
base.start === this.state.potentialArrowAt
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1738,7 +1738,7 @@ export default (superClass: Class<Parser>): Class<Parser> =>
|
|||||||
// There are number of things we are going to "maybe" parse, like type arguments on
|
// There are number of things we are going to "maybe" parse, like type arguments on
|
||||||
// tagged template expressions. If any of them fail, walk it back and continue.
|
// tagged template expressions. If any of them fail, walk it back and continue.
|
||||||
const result = this.tsTryParseAndCatch(() => {
|
const result = this.tsTryParseAndCatch(() => {
|
||||||
if (!noCalls && this.atPossibleAsync(base)) {
|
if (!noCalls && this.atPossibleAsyncArrow(base)) {
|
||||||
// Almost certainly this is a generic async function `async <T>() => ...
|
// Almost certainly this is a generic async function `async <T>() => ...
|
||||||
// But it might be a call with a type argument `async<T>();`
|
// But it might be a call with a type argument `async<T>();`
|
||||||
const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(
|
const asyncArrowFn = this.tsTryParseGenericAsyncArrowFunction(
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
3 + async() => 2
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Unexpected token, expected \";\" (1:12)"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
delete async () => 3;
|
||||||
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"throws": "Unexpected token, expected \";\" (1:16)"
|
||||||
|
}
|
||||||
@ -0,0 +1 @@
|
|||||||
|
4 + async<number>() => 2
|
||||||
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"sourceType": "module",
|
||||||
|
"plugins": ["typescript"],
|
||||||
|
"throws": "Unexpected token, expected \";\" (1:20)"
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user