mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-07 05:41:22 -06:00
Add check for tslib __await helper
This commit is contained in:
parent
a9ad8532d7
commit
e3d54c3b47
@ -15962,7 +15962,7 @@ namespace ts {
|
||||
// From within an async function you can return either a non-promise value or a promise. Any
|
||||
// Promise/A+ compatible implementation will always assimilate any foreign promise, so the
|
||||
// return type of the body is awaited type of the body, wrapped in a native Promise<T> type.
|
||||
return (functionFlags & FunctionFlags.AsyncOrAsyncGenerator) === FunctionFlags.Async
|
||||
return (functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async
|
||||
? createPromiseReturnType(func, widenedType) // Async function
|
||||
: widenedType; // Generator function, AsyncGenerator function, or normal function
|
||||
}
|
||||
@ -16178,7 +16178,7 @@ namespace ts {
|
||||
|
||||
const functionFlags = getFunctionFlags(node);
|
||||
const returnOrPromisedType = node.type &&
|
||||
((functionFlags & FunctionFlags.AsyncOrAsyncGenerator) === FunctionFlags.Async ?
|
||||
((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async ?
|
||||
checkAsyncFunctionReturnType(node) : // Async function
|
||||
getTypeFromTypeNode(node.type)); // AsyncGenerator function, Generator function, or normal function
|
||||
|
||||
@ -16208,7 +16208,7 @@ namespace ts {
|
||||
// its return type annotation.
|
||||
const exprType = checkExpression(<Expression>node.body);
|
||||
if (returnOrPromisedType) {
|
||||
if ((functionFlags & FunctionFlags.AsyncOrAsyncGenerator) === FunctionFlags.Async) { // Async function
|
||||
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) { // Async function
|
||||
const awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.The_return_type_of_an_async_function_must_either_be_a_valid_promise_or_must_not_contain_a_callable_then_member);
|
||||
checkTypeAssignableTo(awaitedType, returnOrPromisedType, node.body);
|
||||
}
|
||||
@ -16948,12 +16948,16 @@ namespace ts {
|
||||
// we are in a yield context.
|
||||
const functionFlags = func && getFunctionFlags(func);
|
||||
if (node.asteriskToken) {
|
||||
if (functionFlags & FunctionFlags.Async) {
|
||||
if (languageVersion < ScriptTarget.ES2017) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegator);
|
||||
}
|
||||
// Async generator functions prior to ESNext require the __await, __asyncDelegator,
|
||||
// and __asyncValues helpers
|
||||
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator &&
|
||||
languageVersion < ScriptTarget.ESNext) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncDelegatorIncludes);
|
||||
}
|
||||
else if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
|
||||
|
||||
// Generator functions prior to ES2015 require the __values helper
|
||||
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Generator &&
|
||||
languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.Values);
|
||||
}
|
||||
}
|
||||
@ -17472,18 +17476,20 @@ namespace ts {
|
||||
}
|
||||
|
||||
const functionFlags = getFunctionFlags(<FunctionLikeDeclaration>node);
|
||||
if ((functionFlags & FunctionFlags.InvalidAsyncOrAsyncGenerator) === FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
|
||||
if (languageVersion < ScriptTarget.ES2015) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
|
||||
if (!(functionFlags & FunctionFlags.Invalid)) {
|
||||
// Async generators prior to ESNext require the __await and __asyncGenerator helpers
|
||||
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.AsyncGenerator && languageVersion < ScriptTarget.ESNext) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncGeneratorIncludes);
|
||||
}
|
||||
}
|
||||
|
||||
if ((functionFlags & FunctionFlags.InvalidGenerator) === FunctionFlags.Generator) {
|
||||
if (functionFlags & FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.AsyncGenerator);
|
||||
// Async functions prior to ES2017 require the __awaiter helper
|
||||
if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async && languageVersion < ScriptTarget.ES2017) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.Awaiter);
|
||||
}
|
||||
else if (languageVersion < ScriptTarget.ES2015) {
|
||||
|
||||
// Generator functions, Async functions, and Async Generator functions prior to
|
||||
// ES2015 require the __generator helper
|
||||
if ((functionFlags & FunctionFlags.AsyncGenerator) !== FunctionFlags.Normal && languageVersion < ScriptTarget.ES2015) {
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.Generator);
|
||||
}
|
||||
}
|
||||
@ -17511,7 +17517,7 @@ namespace ts {
|
||||
|
||||
if (node.type) {
|
||||
const functionFlags = getFunctionFlags(<FunctionDeclaration>node);
|
||||
if ((functionFlags & FunctionFlags.InvalidGenerator) === FunctionFlags.Generator) {
|
||||
if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Generator)) === FunctionFlags.Generator) {
|
||||
const returnType = getTypeFromTypeNode(node.type);
|
||||
if (returnType === voidType) {
|
||||
error(node.type, Diagnostics.A_generator_cannot_have_a_void_type_annotation);
|
||||
@ -17531,7 +17537,7 @@ namespace ts {
|
||||
checkTypeAssignableTo(iterableIteratorInstantiation, returnType, node.type);
|
||||
}
|
||||
}
|
||||
else if ((functionFlags & FunctionFlags.AsyncOrAsyncGenerator) === FunctionFlags.Async) {
|
||||
else if ((functionFlags & FunctionFlags.AsyncGenerator) === FunctionFlags.Async) {
|
||||
checkAsyncFunctionReturnType(<FunctionLikeDeclaration>node);
|
||||
}
|
||||
}
|
||||
@ -19498,11 +19504,14 @@ namespace ts {
|
||||
|
||||
if (node.kind === SyntaxKind.ForOfStatement) {
|
||||
if ((<ForOfStatement>node).awaitModifier) {
|
||||
if (languageVersion < ScriptTarget.ES2017) {
|
||||
const functionFlags = getFunctionFlags(getContainingFunction(node));
|
||||
if ((functionFlags & (FunctionFlags.Invalid | FunctionFlags.Async)) === FunctionFlags.Async && languageVersion < ScriptTarget.ESNext) {
|
||||
// for..await..of in an async function or async generator function prior to ESNext requires the __asyncValues helper
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.ForAwaitOfIncludes);
|
||||
}
|
||||
}
|
||||
else if (languageVersion < ScriptTarget.ES2015 && compilerOptions.downlevelIteration) {
|
||||
else if (compilerOptions.downlevelIteration && languageVersion < ScriptTarget.ES2015) {
|
||||
// for..of prior to ES2015 requires the __values helper when downlevelIteration is enabled
|
||||
checkExternalEmitHelpers(node, ExternalEmitHelpers.ForOfIncludes);
|
||||
}
|
||||
}
|
||||
@ -19932,7 +19941,7 @@ namespace ts {
|
||||
}
|
||||
|
||||
function isUnwrappedReturnTypeVoidOrAny(func: FunctionLikeDeclaration, returnType: Type): boolean {
|
||||
const unwrappedReturnType = (getFunctionFlags(func) & FunctionFlags.AsyncOrAsyncGenerator) === FunctionFlags.Async
|
||||
const unwrappedReturnType = (getFunctionFlags(func) & FunctionFlags.AsyncGenerator) === FunctionFlags.Async
|
||||
? getPromisedTypeOfPromise(returnType) // Async function
|
||||
: returnType; // AsyncGenerator function, Generator function, or normal function
|
||||
return unwrappedReturnType && maybeTypeOfKind(unwrappedReturnType, TypeFlags.Void | TypeFlags.Any);
|
||||
@ -22942,6 +22951,7 @@ namespace ts {
|
||||
case ExternalEmitHelpers.Values: return "__values";
|
||||
case ExternalEmitHelpers.Read: return "__read";
|
||||
case ExternalEmitHelpers.Spread: return "__spread";
|
||||
case ExternalEmitHelpers.Await: return "__await";
|
||||
case ExternalEmitHelpers.AsyncGenerator: return "__asyncGenerator";
|
||||
case ExternalEmitHelpers.AsyncDelegator: return "__asyncDelegator";
|
||||
case ExternalEmitHelpers.AsyncValues: return "__asyncValues";
|
||||
|
||||
@ -884,7 +884,7 @@ namespace ts {
|
||||
|
||||
function createAwaitHelper(context: TransformationContext, expression: Expression) {
|
||||
context.requestEmitHelper(awaitHelper);
|
||||
return createCall(createIdentifier("__await"), /*typeArguments*/ undefined, [expression]);
|
||||
return createCall(getHelperName("__await"), /*typeArguments*/ undefined, [expression]);
|
||||
}
|
||||
|
||||
const asyncGeneratorHelper: EmitHelper = {
|
||||
|
||||
@ -3973,11 +3973,12 @@ namespace ts {
|
||||
Awaiter = 1 << 6, // __awaiter (used by ES2017 async functions transformation)
|
||||
Generator = 1 << 7, // __generator (used by ES2015 generator transformation)
|
||||
Values = 1 << 8, // __values (used by ES2015 for..of and yield* transformations)
|
||||
Read = 1 << 9, // __read (used by ES2015 iterator destructuring transformation)
|
||||
Read = 1 << 9, // __read (used by ES2015 iterator destructuring transformation)
|
||||
Spread = 1 << 10, // __spread (used by ES2015 array spread and argument list spread transformations)
|
||||
AsyncGenerator = 1 << 11, // __asyncGenerator (used by ES2017 async generator transformation)
|
||||
AsyncDelegator = 1 << 12, // __asyncDelegator (used by ES2017 async generator yield* transformation)
|
||||
AsyncValues = 1 << 13, // __asyncValues (used by ES2017 for..await..of transformation)
|
||||
Await = 1 << 11, // __await (used by ES2017 async generator transformation)
|
||||
AsyncGenerator = 1 << 12, // __asyncGenerator (used by ES2017 async generator transformation)
|
||||
AsyncDelegator = 1 << 13, // __asyncDelegator (used by ES2017 async generator yield* transformation)
|
||||
AsyncValues = 1 << 14, // __asyncValues (used by ES2017 for..await..of transformation)
|
||||
|
||||
// Helpers included by ES2015 for..of
|
||||
ForOfIncludes = Values,
|
||||
@ -3985,6 +3986,12 @@ namespace ts {
|
||||
// Helpers included by ES2017 for..await..of
|
||||
ForAwaitOfIncludes = AsyncValues,
|
||||
|
||||
// Helpers included by ES2017 async generators
|
||||
AsyncGeneratorIncludes = Await | AsyncGenerator,
|
||||
|
||||
// Helpers included by yield* in ES2017 async generators
|
||||
AsyncDelegatorIncludes = Await | AsyncDelegator | AsyncValues,
|
||||
|
||||
// Helpers included by ES2015 spread
|
||||
SpreadIncludes = Read | Spread,
|
||||
|
||||
|
||||
@ -1925,16 +1925,18 @@ namespace ts {
|
||||
}
|
||||
|
||||
export const enum FunctionFlags {
|
||||
Normal = 0,
|
||||
Generator = 1 << 0,
|
||||
Async = 1 << 1,
|
||||
AsyncOrAsyncGenerator = Async | Generator,
|
||||
Invalid = 1 << 2,
|
||||
InvalidAsyncOrAsyncGenerator = AsyncOrAsyncGenerator | Invalid,
|
||||
InvalidGenerator = Generator | Invalid,
|
||||
Normal = 0, // Function is a normal function
|
||||
Generator = 1 << 0, // Function is a generator function or async generator function
|
||||
Async = 1 << 1, // Function is an async function or an async generator function
|
||||
Invalid = 1 << 2, // Function is a signature or overload and does not have a body.
|
||||
AsyncGenerator = Async | Generator, // Function is an async generator function
|
||||
}
|
||||
|
||||
export function getFunctionFlags(node: FunctionLikeDeclaration) {
|
||||
export function getFunctionFlags(node: FunctionLikeDeclaration | undefined) {
|
||||
if (!node) {
|
||||
return FunctionFlags.Invalid;
|
||||
}
|
||||
|
||||
let flags = FunctionFlags.Normal;
|
||||
switch (node.kind) {
|
||||
case SyntaxKind.FunctionDeclaration:
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
tests/cases/compiler/main.ts(1,25): error TS2343: This syntax requires an imported helper named '__asyncGenerator', but module 'tslib' has no exported member '__asyncGenerator'.
|
||||
tests/cases/compiler/main.ts(1,25): error TS2343: This syntax requires an imported helper named '__await', but module 'tslib' has no exported member '__await'.
|
||||
tests/cases/compiler/main.ts(1,25): error TS2343: This syntax requires an imported helper named '__generator', but module 'tslib' has no exported member '__generator'.
|
||||
tests/cases/compiler/main.ts(4,5): error TS2343: This syntax requires an imported helper named '__asyncDelegator', but module 'tslib' has no exported member '__asyncDelegator'.
|
||||
tests/cases/compiler/main.ts(4,5): error TS2343: This syntax requires an imported helper named '__asyncValues', but module 'tslib' has no exported member '__asyncValues'.
|
||||
|
||||
|
||||
==== tests/cases/compiler/main.ts (5 errors) ====
|
||||
export async function * f() {
|
||||
~
|
||||
!!! error TS2343: This syntax requires an imported helper named '__asyncGenerator', but module 'tslib' has no exported member '__asyncGenerator'.
|
||||
~
|
||||
!!! error TS2343: This syntax requires an imported helper named '__await', but module 'tslib' has no exported member '__await'.
|
||||
~
|
||||
!!! error TS2343: This syntax requires an imported helper named '__generator', but module 'tslib' has no exported member '__generator'.
|
||||
await 1;
|
||||
yield 2;
|
||||
yield* [3];
|
||||
~~~~~~~~~~
|
||||
!!! error TS2343: This syntax requires an imported helper named '__asyncDelegator', but module 'tslib' has no exported member '__asyncDelegator'.
|
||||
~~~~~~~~~~
|
||||
!!! error TS2343: This syntax requires an imported helper named '__asyncValues', but module 'tslib' has no exported member '__asyncValues'.
|
||||
}
|
||||
|
||||
==== tests/cases/compiler/tslib.d.ts (0 errors) ====
|
||||
export {}
|
||||
|
||||
@ -0,0 +1,37 @@
|
||||
//// [tests/cases/compiler/importHelpersNoHelpersForAsyncGenerators.ts] ////
|
||||
|
||||
//// [main.ts]
|
||||
export async function * f() {
|
||||
await 1;
|
||||
yield 2;
|
||||
yield* [3];
|
||||
}
|
||||
|
||||
//// [tslib.d.ts]
|
||||
export {}
|
||||
|
||||
|
||||
//// [main.js]
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var tslib_1 = require("tslib");
|
||||
function f() {
|
||||
return tslib_1.__asyncGenerator(this, arguments, function f_1() {
|
||||
return tslib_1.__generator(this, function (_a) {
|
||||
switch (_a.label) {
|
||||
case 0: return [4 /*yield*/, tslib_1.__await(1)];
|
||||
case 1:
|
||||
_a.sent();
|
||||
return [4 /*yield*/, 2];
|
||||
case 2:
|
||||
_a.sent();
|
||||
return [5 /*yield**/, tslib_1.__values(tslib_1.__asyncDelegator(tslib_1.__asyncValues([3])))];
|
||||
case 3: return [4 /*yield*/, tslib_1.__await.apply(void 0, [_a.sent()])];
|
||||
case 4:
|
||||
_a.sent();
|
||||
return [2 /*return*/];
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
exports.f = f;
|
||||
@ -0,0 +1,16 @@
|
||||
// @importHelpers: true
|
||||
// @target: es5
|
||||
// @module: commonjs
|
||||
// @lib: esnext
|
||||
// @moduleResolution: classic
|
||||
// @experimentalDecorators: true
|
||||
// @emitDecoratorMetadata: true
|
||||
// @filename: main.ts
|
||||
export async function * f() {
|
||||
await 1;
|
||||
yield 2;
|
||||
yield* [3];
|
||||
}
|
||||
|
||||
// @filename: tslib.d.ts
|
||||
export {}
|
||||
Loading…
x
Reference in New Issue
Block a user