diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index d641cbd4b65e7..68133ac5f1e40 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -7505,7 +7505,11 @@ namespace Parser { case SyntaxKind.LetKeyword: case SyntaxKind.ConstKeyword: case SyntaxKind.UsingKeyword: + return parseVariableStatement(pos, hasJSDoc, modifiersIn); case SyntaxKind.AwaitKeyword: + if (!isAwaitUsingDeclaration()) { + break; + } return parseVariableStatement(pos, hasJSDoc, modifiersIn); case SyntaxKind.FunctionKeyword: return parseFunctionDeclaration(pos, hasJSDoc, modifiersIn); @@ -7534,17 +7538,16 @@ namespace Parser { default: return parseExportDeclaration(pos, hasJSDoc, modifiersIn); } - default: - if (modifiersIn) { - // We reached this point because we encountered decorators and/or modifiers and assumed a declaration - // would follow. For recovery and error reporting purposes, return an incomplete declaration. - const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); - setTextRangePos(missing, pos); - (missing as Mutable).modifiers = modifiersIn; - return missing; - } - return undefined!; // TODO: GH#18217 } + if (modifiersIn) { + // We reached this point because we encountered decorators and/or modifiers and assumed a declaration + // would follow. For recovery and error reporting purposes, return an incomplete declaration. + const missing = createMissingNode(SyntaxKind.MissingDeclaration, /*reportAtCurrentPosition*/ true, Diagnostics.Declaration_expected); + setTextRangePos(missing, pos); + (missing as Mutable).modifiers = modifiersIn; + return missing; + } + return undefined!; // TODO: GH#18217 } function nextTokenIsStringLiteral() { @@ -7677,7 +7680,9 @@ namespace Parser { flags |= NodeFlags.Using; break; case SyntaxKind.AwaitKeyword: - Debug.assert(isAwaitUsingDeclaration()); + if (!isAwaitUsingDeclaration()) { + break; + } flags |= NodeFlags.AwaitUsing; nextToken(); break; diff --git a/tests/baselines/reference/decoratorOnAwait.errors.txt b/tests/baselines/reference/decoratorOnAwait.errors.txt new file mode 100644 index 0000000000000..72a64f3c7d865 --- /dev/null +++ b/tests/baselines/reference/decoratorOnAwait.errors.txt @@ -0,0 +1,11 @@ +decoratorOnAwait.ts(3,5): error TS1146: Declaration expected. + + +==== decoratorOnAwait.ts (1 errors) ==== + declare function dec(target: T): T; + + @dec + +!!! error TS1146: Declaration expected. + await 1 + \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnAwait.js b/tests/baselines/reference/decoratorOnAwait.js new file mode 100644 index 0000000000000..c8a0546e388ff --- /dev/null +++ b/tests/baselines/reference/decoratorOnAwait.js @@ -0,0 +1,11 @@ +//// [tests/cases/conformance/decorators/invalid/decoratorOnAwait.ts] //// + +//// [decoratorOnAwait.ts] +declare function dec(target: T): T; + +@dec +await 1 + + +//// [decoratorOnAwait.js] +await 1; diff --git a/tests/baselines/reference/decoratorOnAwait.symbols b/tests/baselines/reference/decoratorOnAwait.symbols new file mode 100644 index 0000000000000..a2c9ac6a3a10f --- /dev/null +++ b/tests/baselines/reference/decoratorOnAwait.symbols @@ -0,0 +1,15 @@ +//// [tests/cases/conformance/decorators/invalid/decoratorOnAwait.ts] //// + +=== decoratorOnAwait.ts === +declare function dec(target: T): T; +>dec : Symbol(dec, Decl(decoratorOnAwait.ts, 0, 0)) +>T : Symbol(T, Decl(decoratorOnAwait.ts, 0, 21)) +>target : Symbol(target, Decl(decoratorOnAwait.ts, 0, 24)) +>T : Symbol(T, Decl(decoratorOnAwait.ts, 0, 21)) +>T : Symbol(T, Decl(decoratorOnAwait.ts, 0, 21)) + +@dec +>dec : Symbol(dec, Decl(decoratorOnAwait.ts, 0, 0)) + +await 1 + diff --git a/tests/baselines/reference/decoratorOnAwait.types b/tests/baselines/reference/decoratorOnAwait.types new file mode 100644 index 0000000000000..f5a3ec4681d42 --- /dev/null +++ b/tests/baselines/reference/decoratorOnAwait.types @@ -0,0 +1,19 @@ +//// [tests/cases/conformance/decorators/invalid/decoratorOnAwait.ts] //// + +=== decoratorOnAwait.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +> : ^ ^^ ^^ ^^^^^ +>target : T +> : ^ + +@dec +>dec : (target: T) => T +> : ^ ^^ ^^ ^^^^^ + +await 1 +>await 1 : 1 +> : ^ +>1 : 1 +> : ^ + diff --git a/tests/baselines/reference/decoratorOnUsing.errors.txt b/tests/baselines/reference/decoratorOnUsing.errors.txt new file mode 100644 index 0000000000000..1861fa34a32e8 --- /dev/null +++ b/tests/baselines/reference/decoratorOnUsing.errors.txt @@ -0,0 +1,14 @@ +decoratorOnUsing.ts(4,7): error TS1134: Variable declaration expected. + + +==== decoratorOnUsing.ts (1 errors) ==== + declare function dec(target: T): T; + + @dec + using 1 + ~ +!!! error TS1134: Variable declaration expected. + + @dec + using x + \ No newline at end of file diff --git a/tests/baselines/reference/decoratorOnUsing.js b/tests/baselines/reference/decoratorOnUsing.js new file mode 100644 index 0000000000000..47b470c658d9b --- /dev/null +++ b/tests/baselines/reference/decoratorOnUsing.js @@ -0,0 +1,16 @@ +//// [tests/cases/conformance/decorators/invalid/decoratorOnUsing.ts] //// + +//// [decoratorOnUsing.ts] +declare function dec(target: T): T; + +@dec +using 1 + +@dec +using x + + +//// [decoratorOnUsing.js] +using ; +1; +using x; diff --git a/tests/baselines/reference/decoratorOnUsing.symbols b/tests/baselines/reference/decoratorOnUsing.symbols new file mode 100644 index 0000000000000..a173c7e318502 --- /dev/null +++ b/tests/baselines/reference/decoratorOnUsing.symbols @@ -0,0 +1,21 @@ +//// [tests/cases/conformance/decorators/invalid/decoratorOnUsing.ts] //// + +=== decoratorOnUsing.ts === +declare function dec(target: T): T; +>dec : Symbol(dec, Decl(decoratorOnUsing.ts, 0, 0)) +>T : Symbol(T, Decl(decoratorOnUsing.ts, 0, 21)) +>target : Symbol(target, Decl(decoratorOnUsing.ts, 0, 24)) +>T : Symbol(T, Decl(decoratorOnUsing.ts, 0, 21)) +>T : Symbol(T, Decl(decoratorOnUsing.ts, 0, 21)) + +@dec +>dec : Symbol(dec, Decl(decoratorOnUsing.ts, 0, 0)) + +using 1 + +@dec +>dec : Symbol(dec, Decl(decoratorOnUsing.ts, 0, 0)) + +using x +>x : Symbol(x, Decl(decoratorOnUsing.ts, 6, 5)) + diff --git a/tests/baselines/reference/decoratorOnUsing.types b/tests/baselines/reference/decoratorOnUsing.types new file mode 100644 index 0000000000000..cb108be89851e --- /dev/null +++ b/tests/baselines/reference/decoratorOnUsing.types @@ -0,0 +1,25 @@ +//// [tests/cases/conformance/decorators/invalid/decoratorOnUsing.ts] //// + +=== decoratorOnUsing.ts === +declare function dec(target: T): T; +>dec : (target: T) => T +> : ^ ^^ ^^ ^^^^^ +>target : T +> : ^ + +@dec +>dec : (target: T) => T +> : ^ ^^ ^^ ^^^^^ + +using 1 +>1 : 1 +> : ^ + +@dec +>dec : (target: T) => T +> : ^ ^^ ^^ ^^^^^ + +using x +>x : any +> : ^^^ + diff --git a/tests/cases/conformance/decorators/invalid/decoratorOnAwait.ts b/tests/cases/conformance/decorators/invalid/decoratorOnAwait.ts new file mode 100644 index 0000000000000..71fc65e34a036 --- /dev/null +++ b/tests/cases/conformance/decorators/invalid/decoratorOnAwait.ts @@ -0,0 +1,4 @@ +declare function dec(target: T): T; + +@dec +await 1 diff --git a/tests/cases/conformance/decorators/invalid/decoratorOnUsing.ts b/tests/cases/conformance/decorators/invalid/decoratorOnUsing.ts new file mode 100644 index 0000000000000..815da8de4de27 --- /dev/null +++ b/tests/cases/conformance/decorators/invalid/decoratorOnUsing.ts @@ -0,0 +1,8 @@ +// @target: esnext +declare function dec(target: T): T; + +@dec +using 1 + +@dec +using x