Improve parsing in await and yield context (#44680)

* Improve parsing in await and yield context

* Avoid yield and await check in identifier

* Revert "Avoid yield and awaitt check in identifier"

This reverts commit 9644859f29.

* Add some comments
This commit is contained in:
Wenlu Wang
2021-06-22 08:30:55 +08:00
committed by GitHub
parent 9708022537
commit fafe3ff0b4
6 changed files with 388 additions and 3 deletions
+5 -3
View File
@@ -1501,6 +1501,8 @@ namespace ts {
if (token() === SyntaxKind.Identifier) {
return true;
}
// `let await`/`let yield` in [Yield] or [Await] are allowed here and disallowed in the binder.
return token() > SyntaxKind.LastReservedWord;
}
@@ -6122,15 +6124,15 @@ namespace ts {
}
}
function nextTokenIsIdentifierOrStartOfDestructuring() {
function nextTokenIsBindingIdentifierOrStartOfDestructuring() {
nextToken();
return isIdentifier() || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken;
return isBindingIdentifier() || token() === SyntaxKind.OpenBraceToken || token() === SyntaxKind.OpenBracketToken;
}
function isLetDeclaration() {
// In ES6 'let' always starts a lexical declaration if followed by an identifier or {
// or [.
return lookAhead(nextTokenIsIdentifierOrStartOfDestructuring);
return lookAhead(nextTokenIsBindingIdentifierOrStartOfDestructuring);
}
function parseStatement(): Statement {
@@ -0,0 +1,68 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts(14,9): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here.
tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts(18,9): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here.
tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts(22,11): error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here.
tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts(38,9): error TS1359: Identifier expected. 'yield' is a reserved word that cannot be used here.
tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts(42,9): error TS1359: Identifier expected. 'yield' is a reserved word that cannot be used here.
tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts(46,11): error TS1359: Identifier expected. 'yield' is a reserved word that cannot be used here.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts (6 errors) ====
function f_let () {
let await = 1
}
function f1_var () {
var await = 1
}
function f1_const () {
const await = 1
}
async function f2_let () {
let await = 1
~~~~~
!!! error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here.
}
async function f2_var () {
var await = 1
~~~~~
!!! error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here.
}
async function f2_const () {
const await = 1
~~~~~
!!! error TS1359: Identifier expected. 'await' is a reserved word that cannot be used here.
}
function f3_let () {
let yield = 2
}
function f3_var () {
var yield = 2
}
function f3_const () {
const yield = 2
}
function * f4_let () {
let yield = 2;
~~~~~
!!! error TS1359: Identifier expected. 'yield' is a reserved word that cannot be used here.
}
function * f4_var () {
var yield = 2;
~~~~~
!!! error TS1359: Identifier expected. 'yield' is a reserved word that cannot be used here.
}
function * f4_const () {
const yield = 2;
~~~~~
!!! error TS1359: Identifier expected. 'yield' is a reserved word that cannot be used here.
}
@@ -0,0 +1,86 @@
//// [asyncOrYieldAsBindingIdentifier1.ts]
function f_let () {
let await = 1
}
function f1_var () {
var await = 1
}
function f1_const () {
const await = 1
}
async function f2_let () {
let await = 1
}
async function f2_var () {
var await = 1
}
async function f2_const () {
const await = 1
}
function f3_let () {
let yield = 2
}
function f3_var () {
var yield = 2
}
function f3_const () {
const yield = 2
}
function * f4_let () {
let yield = 2;
}
function * f4_var () {
var yield = 2;
}
function * f4_const () {
const yield = 2;
}
//// [asyncOrYieldAsBindingIdentifier1.js]
function f_let() {
let await = 1;
}
function f1_var() {
var await = 1;
}
function f1_const() {
const await = 1;
}
async function f2_let() {
let await = 1;
}
async function f2_var() {
var await = 1;
}
async function f2_const() {
const await = 1;
}
function f3_let() {
let yield = 2;
}
function f3_var() {
var yield = 2;
}
function f3_const() {
const yield = 2;
}
function* f4_let() {
let yield = 2;
}
function* f4_var() {
var yield = 2;
}
function* f4_const() {
const yield = 2;
}
@@ -0,0 +1,84 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts ===
function f_let () {
>f_let : Symbol(f_let, Decl(asyncOrYieldAsBindingIdentifier1.ts, 0, 0))
let await = 1
>await : Symbol(await, Decl(asyncOrYieldAsBindingIdentifier1.ts, 1, 7))
}
function f1_var () {
>f1_var : Symbol(f1_var, Decl(asyncOrYieldAsBindingIdentifier1.ts, 2, 1))
var await = 1
>await : Symbol(await, Decl(asyncOrYieldAsBindingIdentifier1.ts, 5, 7))
}
function f1_const () {
>f1_const : Symbol(f1_const, Decl(asyncOrYieldAsBindingIdentifier1.ts, 6, 1))
const await = 1
>await : Symbol(await, Decl(asyncOrYieldAsBindingIdentifier1.ts, 9, 9))
}
async function f2_let () {
>f2_let : Symbol(f2_let, Decl(asyncOrYieldAsBindingIdentifier1.ts, 10, 1))
let await = 1
>await : Symbol(await, Decl(asyncOrYieldAsBindingIdentifier1.ts, 13, 7))
}
async function f2_var () {
>f2_var : Symbol(f2_var, Decl(asyncOrYieldAsBindingIdentifier1.ts, 14, 1))
var await = 1
>await : Symbol(await, Decl(asyncOrYieldAsBindingIdentifier1.ts, 17, 7))
}
async function f2_const () {
>f2_const : Symbol(f2_const, Decl(asyncOrYieldAsBindingIdentifier1.ts, 18, 1))
const await = 1
>await : Symbol(await, Decl(asyncOrYieldAsBindingIdentifier1.ts, 21, 9))
}
function f3_let () {
>f3_let : Symbol(f3_let, Decl(asyncOrYieldAsBindingIdentifier1.ts, 22, 1))
let yield = 2
>yield : Symbol(yield, Decl(asyncOrYieldAsBindingIdentifier1.ts, 25, 7))
}
function f3_var () {
>f3_var : Symbol(f3_var, Decl(asyncOrYieldAsBindingIdentifier1.ts, 26, 1))
var yield = 2
>yield : Symbol(yield, Decl(asyncOrYieldAsBindingIdentifier1.ts, 29, 7))
}
function f3_const () {
>f3_const : Symbol(f3_const, Decl(asyncOrYieldAsBindingIdentifier1.ts, 30, 1))
const yield = 2
>yield : Symbol(yield, Decl(asyncOrYieldAsBindingIdentifier1.ts, 33, 9))
}
function * f4_let () {
>f4_let : Symbol(f4_let, Decl(asyncOrYieldAsBindingIdentifier1.ts, 34, 1))
let yield = 2;
>yield : Symbol(yield, Decl(asyncOrYieldAsBindingIdentifier1.ts, 37, 7))
}
function * f4_var () {
>f4_var : Symbol(f4_var, Decl(asyncOrYieldAsBindingIdentifier1.ts, 38, 1))
var yield = 2;
>yield : Symbol(yield, Decl(asyncOrYieldAsBindingIdentifier1.ts, 41, 7))
}
function * f4_const () {
>f4_const : Symbol(f4_const, Decl(asyncOrYieldAsBindingIdentifier1.ts, 42, 1))
const yield = 2;
>yield : Symbol(yield, Decl(asyncOrYieldAsBindingIdentifier1.ts, 45, 9))
}
@@ -0,0 +1,96 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncOrYieldAsBindingIdentifier1.ts ===
function f_let () {
>f_let : () => void
let await = 1
>await : number
>1 : 1
}
function f1_var () {
>f1_var : () => void
var await = 1
>await : number
>1 : 1
}
function f1_const () {
>f1_const : () => void
const await = 1
>await : 1
>1 : 1
}
async function f2_let () {
>f2_let : () => Promise<void>
let await = 1
>await : number
>1 : 1
}
async function f2_var () {
>f2_var : () => Promise<void>
var await = 1
>await : number
>1 : 1
}
async function f2_const () {
>f2_const : () => Promise<void>
const await = 1
>await : 1
>1 : 1
}
function f3_let () {
>f3_let : () => void
let yield = 2
>yield : number
>2 : 2
}
function f3_var () {
>f3_var : () => void
var yield = 2
>yield : number
>2 : 2
}
function f3_const () {
>f3_const : () => void
const yield = 2
>yield : 2
>2 : 2
}
function * f4_let () {
>f4_let : () => Generator<never, void, unknown>
let yield = 2;
>yield : number
>2 : 2
}
function * f4_var () {
>f4_var : () => Generator<never, void, unknown>
var yield = 2;
>yield : number
>2 : 2
}
function * f4_const () {
>f4_const : () => Generator<never, void, unknown>
const yield = 2;
>yield : 2
>2 : 2
}
@@ -0,0 +1,49 @@
// @target: esnext
function f_let () {
let await = 1
}
function f1_var () {
var await = 1
}
function f1_const () {
const await = 1
}
async function f2_let () {
let await = 1
}
async function f2_var () {
var await = 1
}
async function f2_const () {
const await = 1
}
function f3_let () {
let yield = 2
}
function f3_var () {
var yield = 2
}
function f3_const () {
const yield = 2
}
function * f4_let () {
let yield = 2;
}
function * f4_var () {
var yield = 2;
}
function * f4_const () {
const yield = 2;
}