Support top level "for await of" (#37424)

* Support Top Level "for await of".

* Add test cases for top level "for await of".

* Apply suggestions from code review

* add test cases

* remove redundant variables

* fix test baselines

* Update diagnostic message and tests

Co-authored-by: Ron Buckton <ron.buckton@microsoft.com>
This commit is contained in:
M.Yoshimura 2021-01-26 06:40:45 +09:00 committed by GitHub
parent f529115b41
commit 701493fb80
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 606 additions and 61 deletions

View File

@ -40179,19 +40179,33 @@ namespace ts {
}
if (forInOrOfStatement.kind === SyntaxKind.ForOfStatement && forInOrOfStatement.awaitModifier) {
if ((forInOrOfStatement.flags & NodeFlags.AwaitContext) === NodeFlags.None) {
// use of 'for-await-of' in non-async function
if (!(forInOrOfStatement.flags & NodeFlags.AwaitContext)) {
const sourceFile = getSourceFileOfNode(forInOrOfStatement);
if (!hasParseDiagnostics(sourceFile)) {
const diagnostic = createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator);
const func = getContainingFunction(forInOrOfStatement);
if (func && func.kind !== SyntaxKind.Constructor) {
Debug.assert((getFunctionFlags(func) & FunctionFlags.Async) === 0, "Enclosing function should never be an async function.");
const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async);
addRelatedInfo(diagnostic, relatedInfo);
if (isInTopLevelContext(forInOrOfStatement)) {
if (!hasParseDiagnostics(sourceFile)) {
if (!isEffectiveExternalModule(sourceFile, compilerOptions)) {
diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier,
Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module));
}
if ((moduleKind !== ModuleKind.ESNext && moduleKind !== ModuleKind.System) || languageVersion < ScriptTarget.ES2017) {
diagnostics.add(createDiagnosticForNode(forInOrOfStatement.awaitModifier,
Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher));
}
}
}
else {
// use of 'for-await-of' in non-async function
if (!hasParseDiagnostics(sourceFile)) {
const diagnostic = createDiagnosticForNode(forInOrOfStatement.awaitModifier, Diagnostics.for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules);
const func = getContainingFunction(forInOrOfStatement);
if (func && func.kind !== SyntaxKind.Constructor) {
Debug.assert((getFunctionFlags(func) & FunctionFlags.Async) === 0, "Enclosing function should never be an async function.");
const relatedInfo = createDiagnosticForNode(func, Diagnostics.Did_you_mean_to_mark_this_function_as_async);
addRelatedInfo(diagnostic, relatedInfo);
}
diagnostics.add(diagnostic);
return true;
}
diagnostics.add(diagnostic);
return true;
}
return false;
}

View File

@ -307,7 +307,7 @@
"category": "Error",
"code": 1102
},
"A 'for-await-of' statement is only allowed within an async function or async generator.": {
"'for await' loops are only allowed within async functions and at the top levels of modules.": {
"category": "Error",
"code": 1103
},
@ -1352,6 +1352,15 @@
"category": "Message",
"code": 1430
},
"'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.": {
"category": "Error",
"code": 1431
},
"Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.": {
"category": "Error",
"code": 1432
},
"The types of '{0}' are incompatible between these types.": {
"category": "Error",
"code": 2200

View File

@ -1,7 +1,10 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code],
errorCodes: [
Diagnostics.await_expressions_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code,
Diagnostics.for_await_loops_are_only_allowed_at_the_top_level_of_a_file_when_that_file_is_a_module_but_this_file_has_no_imports_or_exports_Consider_adding_an_empty_export_to_make_this_file_a_module.code,
],
getCodeActions: context => {
const { sourceFile } = context;
const changes = textChanges.ChangeTracker.with(context, changes => {

View File

@ -3,7 +3,7 @@ namespace ts.codefix {
const fixId = "fixAwaitInSyncFunction";
const errorCodes = [
Diagnostics.await_expressions_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code,
Diagnostics.A_for_await_of_statement_is_only_allowed_within_an_async_function_or_async_generator.code,
Diagnostics.for_await_loops_are_only_allowed_within_async_functions_and_at_the_top_levels_of_modules.code,
];
registerCodeFix({
errorCodes,

View File

@ -1,7 +1,10 @@
/* @internal */
namespace ts.codefix {
registerCodeFix({
errorCodes: [Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code],
errorCodes: [
Diagnostics.Top_level_await_expressions_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code,
Diagnostics.Top_level_for_await_loops_are_only_allowed_when_the_module_option_is_set_to_esnext_or_system_and_the_target_option_is_set_to_es2017_or_higher.code,
],
getCodeActions: context => {
const compilerOptions = context.program.getCompilerOptions();
const { configFile } = compilerOptions;

View File

@ -1,18 +1,18 @@
tests/cases/compiler/awaitInNonAsyncFunction.ts(4,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(4,7): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(5,10): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(9,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(9,7): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(10,10): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(14,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(14,7): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(15,3): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(19,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(19,7): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(20,10): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(24,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(24,7): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(25,9): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(30,9): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(30,9): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(31,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(34,7): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(34,7): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(35,5): error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
tests/cases/compiler/awaitInNonAsyncFunction.ts(39,5): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/compiler/awaitInNonAsyncFunction.ts(39,5): error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
@ -22,7 +22,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
function normalFunc(p: Promise<number>) {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:3:10: Did you mean to mark this function as 'async'?
return await p;
~~~~~
@ -33,7 +33,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
export function exportedFunc(p: Promise<number>) {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:8:17: Did you mean to mark this function as 'async'?
return await p;
~~~~~
@ -44,7 +44,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
const functionExpression = function(p: Promise<number>) {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:13:28: Did you mean to mark this function as 'async'?
await p;
~~~~~
@ -55,7 +55,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
const arrowFunc = (p: Promise<number>) => {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:18:19: Did you mean to mark this function as 'async'?
return await p;
~~~~~
@ -66,7 +66,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
function* generatorFunc(p: Promise<number>) {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:23:11: Did you mean to mark this function as 'async'?
yield await p;
~~~~~
@ -78,7 +78,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
constructor(p: Promise<number>) {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
await p;
~~~~~
!!! error TS1308: 'await' expressions are only allowed within async functions and at the top levels of modules.
@ -86,7 +86,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
method(p: Promise<number>) {
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/compiler/awaitInNonAsyncFunction.ts:33:3: Did you mean to mark this function as 'async'?
await p;
~~~~~
@ -97,7 +97,7 @@ tests/cases/compiler/awaitInNonAsyncFunction.ts(40,1): error TS1378: Top-level '
for await (const _ of []);
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
await null;
~~~~~
!!! error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.

View File

@ -3,28 +3,34 @@ tests/cases/conformance/parser/ecmascript2018/forAwait/forAwaitInWithDeclIsError
tests/cases/conformance/parser/ecmascript2018/forAwait/forAwaitInWithExprIsError.ts(1,12): error TS2304: Cannot find name 'x'.
tests/cases/conformance/parser/ecmascript2018/forAwait/forAwaitInWithExprIsError.ts(1,14): error TS1005: 'of' expected.
tests/cases/conformance/parser/ecmascript2018/forAwait/forAwaitInWithExprIsError.ts(1,17): error TS2304: Cannot find name 'y'.
tests/cases/conformance/parser/ecmascript2018/forAwait/inFunctionDeclWithDeclIsError.ts(3,9): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/conformance/parser/ecmascript2018/forAwait/inFunctionDeclWithExprIsError.ts(3,9): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/conformance/parser/ecmascript2018/forAwait/inGeneratorWithDeclIsError.ts(3,9): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/conformance/parser/ecmascript2018/forAwait/inGeneratorWithExprIsError.ts(3,9): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithDeclIsError.ts(1,5): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/conformance/parser/ecmascript2018/forAwait/inFunctionDeclWithDeclIsError.ts(3,9): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/conformance/parser/ecmascript2018/forAwait/inFunctionDeclWithExprIsError.ts(3,9): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/conformance/parser/ecmascript2018/forAwait/inGeneratorWithDeclIsError.ts(3,9): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/conformance/parser/ecmascript2018/forAwait/inGeneratorWithExprIsError.ts(3,9): error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithDeclIsError.ts(1,5): error TS1431: 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithDeclIsError.ts(1,5): error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithDeclIsError.ts(1,23): error TS2304: Cannot find name 'y'.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts(1,5): error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts(1,5): error TS1431: 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts(1,5): error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts(1,12): error TS2304: Cannot find name 'x'.
tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts(1,17): error TS2304: Cannot find name 'y'.
==== tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithDeclIsError.ts (2 errors) ====
==== tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithDeclIsError.ts (3 errors) ====
for await (const x of y) {
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1431: 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
~~~~~
!!! error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
~
!!! error TS2304: Cannot find name 'y'.
}
==== tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts (3 errors) ====
==== tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.ts (4 errors) ====
for await (x of y) {
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1431: 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
~~~~~
!!! error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
~
!!! error TS2304: Cannot find name 'x'.
~
@ -51,7 +57,7 @@ tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.t
let y: any;
for await (const x of y) {
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/conformance/parser/ecmascript2018/forAwait/inFunctionDeclWithDeclIsError.ts:1:10: Did you mean to mark this function as 'async'?
}
}
@ -60,7 +66,7 @@ tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.t
let x: any, y: any;
for await (x of y) {
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/conformance/parser/ecmascript2018/forAwait/inFunctionDeclWithExprIsError.ts:1:10: Did you mean to mark this function as 'async'?
}
}
@ -93,7 +99,7 @@ tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.t
let y: any;
for await (const x of y) {
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/conformance/parser/ecmascript2018/forAwait/inGeneratorWithDeclIsError.ts:1:11: Did you mean to mark this function as 'async'?
}
}
@ -102,7 +108,7 @@ tests/cases/conformance/parser/ecmascript2018/forAwait/topLevelWithExprIsError.t
let x: any, y: any;
for await (x of y) {
~~~~~
!!! error TS1103: A 'for-await-of' statement is only allowed within an async function or async generator.
!!! error TS1103: 'for await' loops are only allowed within async functions and at the top levels of modules.
!!! related TS1356 tests/cases/conformance/parser/ecmascript2018/forAwait/inGeneratorWithExprIsError.ts:1:11: Did you mean to mark this function as 'async'?
}
}

View File

@ -1,5 +1,6 @@
tests/cases/conformance/externalModules/index.ts(2,1): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/externalModules/index.ts(46,3): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/externalModules/other.ts(9,5): error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/externalModules/index.ts (2 errors) ====
@ -72,8 +73,18 @@ tests/cases/conformance/externalModules/index.ts(46,3): error TS1378: Top-level
await
1;
==== tests/cases/conformance/externalModules/other.ts (0 errors) ====
==== tests/cases/conformance/externalModules/other.ts (1 errors) ====
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
~~~~~
!!! error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
item;
}

View File

@ -70,12 +70,36 @@ await
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}
//// [other.js]
var e_1, _a;
const _await = 1;
// await allowed in aliased export
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
try {
for (var arr_1 = __asyncValues(arr), arr_1_1; arr_1_1 = await arr_1.next(), !arr_1_1.done;) {
const item = arr_1_1.value;
item;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) await _a.call(arr_1);
}
finally { if (e_1) throw e_1.error; }
}
//// [index.js]
export const x = 1;
await x;

View File

@ -126,3 +126,18 @@ export { _await as await };
>_await : Symbol(_await, Decl(other.ts, 0, 5))
>await : Symbol(await, Decl(other.ts, 3, 8))
// for-await-of
const arr = [Promise.resolve()];
>arr : Symbol(arr, Decl(other.ts, 6, 5))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
for await (const item of arr) {
>item : Symbol(item, Decl(other.ts, 8, 16))
>arr : Symbol(arr, Decl(other.ts, 6, 5))
item;
>item : Symbol(item, Decl(other.ts, 8, 16))
}

View File

@ -176,3 +176,20 @@ export { _await as await };
>_await : 1
>await : 1
// for-await-of
const arr = [Promise.resolve()];
>arr : Promise<void>[]
>[Promise.resolve()] : Promise<void>[]
>Promise.resolve() : Promise<void>
>Promise.resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
>Promise : PromiseConstructor
>resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
for await (const item of arr) {
>item : void
>arr : Promise<void>[]
item;
>item : void
}

View File

@ -70,12 +70,36 @@ await
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}
//// [other.js]
var e_1, _a;
const _await = 1;
// await allowed in aliased export
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
try {
for (var arr_1 = __asyncValues(arr), arr_1_1; arr_1_1 = await arr_1.next(), !arr_1_1.done;) {
const item = arr_1_1.value;
item;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) await _a.call(arr_1);
}
finally { if (e_1) throw e_1.error; }
}
//// [index.js]
export const x = 1;
await x;

View File

@ -126,3 +126,18 @@ export { _await as await };
>_await : Symbol(_await, Decl(other.ts, 0, 5))
>await : Symbol(await, Decl(other.ts, 3, 8))
// for-await-of
const arr = [Promise.resolve()];
>arr : Symbol(arr, Decl(other.ts, 6, 5))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
for await (const item of arr) {
>item : Symbol(item, Decl(other.ts, 8, 16))
>arr : Symbol(arr, Decl(other.ts, 6, 5))
item;
>item : Symbol(item, Decl(other.ts, 8, 16))
}

View File

@ -176,3 +176,20 @@ export { _await as await };
>_await : 1
>await : 1
// for-await-of
const arr = [Promise.resolve()];
>arr : Promise<void>[]
>[Promise.resolve()] : Promise<void>[]
>Promise.resolve() : Promise<void>
>Promise.resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
>Promise : PromiseConstructor
>resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
for await (const item of arr) {
>item : void
>arr : Promise<void>[]
item;
>item : void
}

View File

@ -1,5 +1,6 @@
tests/cases/conformance/externalModules/index.ts(2,1): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/externalModules/index.ts(46,3): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
tests/cases/conformance/externalModules/other.ts(9,5): error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
==== tests/cases/conformance/externalModules/index.ts (2 errors) ====
@ -72,8 +73,18 @@ tests/cases/conformance/externalModules/index.ts(46,3): error TS1378: Top-level
await
1;
==== tests/cases/conformance/externalModules/other.ts (0 errors) ====
==== tests/cases/conformance/externalModules/other.ts (1 errors) ====
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
~~~~~
!!! error TS1432: Top-level 'for await' loops are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher.
item;
}

View File

@ -70,18 +70,41 @@ await
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}
//// [other.js]
System.register([], function (exports_1, context_1) {
"use strict";
var _await;
var e_1, _a, _await, arr;
var __moduleName = context_1 && context_1.id;
return {
setters: [],
execute: function () {
execute: async function () {
_await = 1;
exports_1("await", _await);
// for-await-of
arr = [Promise.resolve()];
try {
for (var arr_1 = __asyncValues(arr), arr_1_1; arr_1_1 = await arr_1.next(), !arr_1_1.done;) {
const item = arr_1_1.value;
item;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) await _a.call(arr_1);
}
finally { if (e_1) throw e_1.error; }
}
}
};
});

View File

@ -126,3 +126,18 @@ export { _await as await };
>_await : Symbol(_await, Decl(other.ts, 0, 5))
>await : Symbol(await, Decl(other.ts, 3, 8))
// for-await-of
const arr = [Promise.resolve()];
>arr : Symbol(arr, Decl(other.ts, 6, 5))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
for await (const item of arr) {
>item : Symbol(item, Decl(other.ts, 8, 16))
>arr : Symbol(arr, Decl(other.ts, 6, 5))
item;
>item : Symbol(item, Decl(other.ts, 8, 16))
}

View File

@ -176,3 +176,20 @@ export { _await as await };
>_await : 1
>await : 1
// for-await-of
const arr = [Promise.resolve()];
>arr : Promise<void>[]
>[Promise.resolve()] : Promise<void>[]
>Promise.resolve() : Promise<void>
>Promise.resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
>Promise : PromiseConstructor
>resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
for await (const item of arr) {
>item : void
>arr : Promise<void>[]
item;
>item : void
}

View File

@ -70,18 +70,41 @@ await
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}
//// [other.js]
System.register([], function (exports_1, context_1) {
"use strict";
var _await;
var e_1, _a, _await, arr;
var __moduleName = context_1 && context_1.id;
return {
setters: [],
execute: function () {
execute: async function () {
_await = 1;
exports_1("await", _await);
// for-await-of
arr = [Promise.resolve()];
try {
for (var arr_1 = __asyncValues(arr), arr_1_1; arr_1_1 = await arr_1.next(), !arr_1_1.done;) {
const item = arr_1_1.value;
item;
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (arr_1_1 && !arr_1_1.done && (_a = arr_1.return)) await _a.call(arr_1);
}
finally { if (e_1) throw e_1.error; }
}
}
};
});

View File

@ -126,3 +126,18 @@ export { _await as await };
>_await : Symbol(_await, Decl(other.ts, 0, 5))
>await : Symbol(await, Decl(other.ts, 3, 8))
// for-await-of
const arr = [Promise.resolve()];
>arr : Symbol(arr, Decl(other.ts, 6, 5))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
for await (const item of arr) {
>item : Symbol(item, Decl(other.ts, 8, 16))
>arr : Symbol(arr, Decl(other.ts, 6, 5))
item;
>item : Symbol(item, Decl(other.ts, 8, 16))
}

View File

@ -176,3 +176,20 @@ export { _await as await };
>_await : 1
>await : 1
// for-await-of
const arr = [Promise.resolve()];
>arr : Promise<void>[]
>[Promise.resolve()] : Promise<void>[]
>Promise.resolve() : Promise<void>
>Promise.resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
>Promise : PromiseConstructor
>resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
for await (const item of arr) {
>item : void
>arr : Promise<void>[]
item;
>item : void
}

View File

@ -1,11 +1,20 @@
tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,1): error TS1375: 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(1,7): error TS2304: Cannot find name 'x'.
tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts(5,5): error TS1431: 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
==== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts (2 errors) ====
==== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts (3 errors) ====
await x;
~~~~~
!!! error TS1375: 'await' expressions are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
~
!!! error TS2304: Cannot find name 'x'.
const arr = [Promise.resolve()];
for await (const item of arr) {
~~~~~
!!! error TS1431: 'for await' loops are only allowed at the top level of a file when that file is a module, but this file has no imports or exports. Consider adding an empty 'export {}' to make this file a module.
item;
}

View File

@ -1,6 +1,16 @@
//// [topLevelAwaitNonModule.ts]
await x;
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}
//// [topLevelAwaitNonModule.js]
await x;
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}

View File

@ -1,4 +1,17 @@
=== tests/cases/conformance/externalModules/topLevelAwaitNonModule.ts ===
await x;
No type information for this code.
No type information for this code.
const arr = [Promise.resolve()];
>arr : Symbol(arr, Decl(topLevelAwaitNonModule.ts, 2, 5))
>Promise.resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
>Promise : Symbol(Promise, Decl(lib.es5.d.ts, --, --), Decl(lib.es2015.iterable.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.symbol.wellknown.d.ts, --, --), Decl(lib.es2018.promise.d.ts, --, --))
>resolve : Symbol(PromiseConstructor.resolve, Decl(lib.es2015.promise.d.ts, --, --), Decl(lib.es2015.promise.d.ts, --, --))
for await (const item of arr) {
>item : Symbol(item, Decl(topLevelAwaitNonModule.ts, 4, 16))
>arr : Symbol(arr, Decl(topLevelAwaitNonModule.ts, 2, 5))
item;
>item : Symbol(item, Decl(topLevelAwaitNonModule.ts, 4, 16))
}

View File

@ -3,3 +3,19 @@ await x;
>await x : any
>x : any
const arr = [Promise.resolve()];
>arr : Promise<void>[]
>[Promise.resolve()] : Promise<void>[]
>Promise.resolve() : Promise<void>
>Promise.resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
>Promise : PromiseConstructor
>resolve : { (): Promise<void>; <T>(value: T | PromiseLike<T>): Promise<T>; }
for await (const item of arr) {
>item : void
>arr : Promise<void>[]
item;
>item : void
}

View File

@ -72,4 +72,11 @@ await
const _await = 1;
// await allowed in aliased export
export { _await as await };
export { _await as await };
// for-await-of
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}

View File

@ -1,3 +1,9 @@
// @target: esnext
// @module: esnext
await x;
const arr = [Promise.resolve()];
for await (const item of arr) {
item;
}

View File

@ -0,0 +1,14 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// }
////}
// Cannot fix module when default module option is `commonjs`...
verify.not.codeFixAvailable("fixModuleOption");

View File

@ -0,0 +1,15 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// "target": "es2017",
//// "module": "esnext"
//// }
////}
verify.not.codeFixAvailable("fixModuleOption");

View File

@ -0,0 +1,25 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// "module": "es2015"
//// }
////}
verify.codeFix({
description: [ts.Diagnostics.Set_the_module_option_in_your_configuration_file_to_0.message, "esnext"],
index: 0,
newFileContent: {
"/dir/tsconfig.json":
`{
"compilerOptions": {
"module": "esnext"
}
}`
}
});

View File

@ -0,0 +1,11 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
////}
// cannot fix module when default options are applied
verify.not.codeFixAvailable("fixModuleOption");

View File

@ -0,0 +1,8 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
verify.not.codeFixAvailable("fixModuleOption");

View File

@ -0,0 +1,14 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// "target": "es2017"
//// }
////}
verify.not.codeFixAvailable("fixTargetOption");
verify.codeFixAvailable("fixModuleOption");

View File

@ -0,0 +1,22 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// "target": "esnext",
//// "module": "esnext"
//// }
////}
verify.codeFix({
description: ts.Diagnostics.Add_export_to_make_this_file_into_a_module.message,
index: 0,
newFileContent:
`declare const p: number[];
for await (const _ of p);
export { };
`
});

View File

@ -0,0 +1,25 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// }
////}
verify.codeFix({
description: [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0.message, "es2017"],
index: 0,
newFileContent: {
"/dir/tsconfig.json":
`{
"compilerOptions": {
"target": "es2017",
"module": "commonjs"
}
}`
}
});

View File

@ -0,0 +1,15 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// "target": "es2017",
//// "module": "esnext"
//// }
////}
verify.not.codeFixAvailable();

View File

@ -0,0 +1,25 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
//// "compilerOptions": {
//// "target": "es2015"
//// }
////}
verify.codeFix({
description: [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0.message, "es2017"],
index: 1,
newFileContent: {
"/dir/tsconfig.json":
`{
"compilerOptions": {
"target": "es2017"
}
}`
}
});

View File

@ -0,0 +1,23 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
// @filename: /dir/tsconfig.json
////{
////}
verify.codeFix({
description: [ts.Diagnostics.Set_the_target_option_in_your_configuration_file_to_0.message, "es2017"],
index: 0,
newFileContent: {
"/dir/tsconfig.json":
`{
"compilerOptions": {
"target": "es2017",
"module": "commonjs"
}
}`
}
});

View File

@ -0,0 +1,8 @@
/// <reference path="fourslash.ts" />
// @filename: /dir/a.ts
////declare const p: number[];
////for await (const _ of p);
////export {};
verify.not.codeFixAvailable();