Add check for tslib __await helper

This commit is contained in:
Ron Buckton
2017-05-04 13:09:35 -07:00
parent 729c1e19ab
commit cbeb11eabf
7 changed files with 134 additions and 35 deletions

View File

@@ -15987,7 +15987,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
}
@@ -16203,7 +16203,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
@@ -16233,7 +16233,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);
}
@@ -16973,12 +16973,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);
}
}
@@ -17497,18 +17501,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);
}
}
@@ -17536,7 +17542,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);
@@ -17556,7 +17562,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);
}
}
@@ -19523,11 +19529,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);
}
}
@@ -19957,7 +19966,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);
@@ -22964,6 +22973,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";

View File

@@ -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 = {

View File

@@ -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,

View File

@@ -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: