Merge pull request #3078 from Microsoft/asyncFunctions

Async Functions for ES6
This commit is contained in:
Ron Buckton 2015-07-01 09:50:12 -07:00
commit b2a871dcfb
315 changed files with 5110 additions and 918 deletions

View File

@ -106,6 +106,8 @@ namespace ts {
let globals: SymbolTable = {};
let globalESSymbolConstructorSymbol: Symbol;
let getGlobalPromiseConstructorSymbol: () => Symbol;
let globalObjectType: ObjectType;
let globalFunctionType: ObjectType;
@ -129,14 +131,22 @@ namespace ts {
let getGlobalPropertyDecoratorType: () => ObjectType;
let getGlobalMethodDecoratorType: () => ObjectType;
let getGlobalTypedPropertyDescriptorType: () => ObjectType;
let getGlobalPromiseType: () => ObjectType;
let tryGetGlobalPromiseType: () => ObjectType;
let getGlobalPromiseLikeType: () => ObjectType;
let getInstantiatedGlobalPromiseLikeType: () => ObjectType;
let getGlobalPromiseConstructorLikeType: () => ObjectType;
let getGlobalThenableType: () => ObjectType;
let tupleTypes: Map<TupleType> = {};
let unionTypes: Map<UnionType> = {};
let stringLiteralTypes: Map<StringLiteralType> = {};
let emitExtends = false;
let emitDecorate = false;
let emitParam = false;
let emitAwaiter = false;
let emitGenerator = false;
let resolutionTargets: Object[] = [];
let resolutionResults: boolean[] = [];
@ -144,6 +154,7 @@ namespace ts {
let symbolLinks: SymbolLinks[] = [];
let nodeLinks: NodeLinks[] = [];
let potentialThisCollisions: Node[] = [];
let awaitedTypeStack: number[] = [];
let diagnostics = createDiagnosticCollection();
@ -3804,6 +3815,10 @@ namespace ts {
function getGlobalType(name: string, arity = 0): ObjectType {
return getTypeOfGlobalSymbol(getGlobalTypeSymbol(name), arity);
}
function tryGetGlobalType(name: string, arity = 0): ObjectType {
return getTypeOfGlobalSymbol(getGlobalSymbol(name, SymbolFlags.Type, /*diagnostic*/ undefined), arity);
}
/**
* Returns a type that is inside a namespace at the global scope, e.g.
@ -4019,7 +4034,7 @@ namespace ts {
}
return links.resolvedType;
}
function getTypeFromTypeNode(node: TypeNode): Type {
switch (node.kind) {
case SyntaxKind.AnyKeyword:
@ -5572,9 +5587,11 @@ namespace ts {
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.PrefixUnaryExpression:
case SyntaxKind.DeleteExpression:
case SyntaxKind.AwaitExpression:
case SyntaxKind.TypeOfExpression:
case SyntaxKind.VoidExpression:
case SyntaxKind.PostfixUnaryExpression:
case SyntaxKind.YieldExpression:
case SyntaxKind.ConditionalExpression:
case SyntaxKind.SpreadElementExpression:
case SyntaxKind.Block:
@ -5891,8 +5908,18 @@ namespace ts {
// will be bound to non-arrow function that contain this arrow function. This results in inconsistent behavior.
// To avoid that we will give an error to users if they use arguments objects in arrow function so that they
// can explicitly bound arguments objects
if (symbol === argumentsSymbol && getContainingFunction(node).kind === SyntaxKind.ArrowFunction && languageVersion < ScriptTarget.ES6) {
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
if (symbol === argumentsSymbol) {
let container = getContainingFunction(node);
if (container.kind === SyntaxKind.ArrowFunction) {
if (languageVersion < ScriptTarget.ES6) {
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_arrow_function_in_ES3_and_ES5_Consider_using_a_standard_function_expression);
}
}
if (node.parserContextFlags & ParserContextFlags.Await) {
getNodeLinks(container).flags |= NodeCheckFlags.CaptureArguments;
getNodeLinks(node).flags |= NodeCheckFlags.LexicalArguments;
}
}
if (symbol.flags & SymbolFlags.Alias && !isInTypeQuery(node) && !isConstEnumOrConstEnumOnlyModule(resolveAlias(symbol))) {
@ -6203,6 +6230,18 @@ namespace ts {
return undefined;
}
function isInParameterInitializerBeforeContainingFunction(node: Node) {
while (node.parent && !isFunctionLike(node.parent)) {
if (node.parent.kind === SyntaxKind.Parameter && (<ParameterDeclaration>node.parent).initializer === node) {
return true;
}
node = node.parent;
}
return false;
}
function getContextualReturnType(functionDecl: FunctionLikeDeclaration): Type {
// If the containing function has a return type annotation, is a constructor, or is a get accessor whose
// corresponding set accessor has a type annotation, return statements in the function are contextually typed
@ -8563,15 +8602,36 @@ namespace ts {
links.type = instantiateType(getTypeOfSymbol(lastOrUndefined(context.parameters)), mapper);
}
}
function createPromiseType(promisedType: Type): Type {
// creates a `Promise<T>` type where `T` is the promisedType argument
let globalPromiseType = getGlobalPromiseType();
if (globalPromiseType !== emptyObjectType) {
// if the promised type is itself a promise, get the underlying type; otherwise, fallback to the promised type
promisedType = getAwaitedType(promisedType);
return createTypeReference(<GenericType>globalPromiseType, [promisedType]);
}
return emptyObjectType;
}
function getReturnTypeFromBody(func: FunctionLikeDeclaration, contextualMapper?: TypeMapper): Type {
let contextualSignature = getContextualSignatureForFunctionLikeDeclaration(func);
if (!func.body) {
return unknownType;
}
let isAsync = isAsyncFunctionLike(func);
let type: Type;
if (func.body.kind !== SyntaxKind.Block) {
type = checkExpressionCached(<Expression>func.body, contextualMapper);
type = checkExpressionCached(<Expression>func.body, contextualMapper);
if (isAsync) {
// 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 should be unwrapped to its awaited type, which we will wrap in
// the native Promise<T> type later in this function.
type = checkAwaitedType(type, func, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
}
}
else {
let types: Type[];
@ -8588,12 +8648,23 @@ namespace ts {
}
}
else {
types = checkAndAggregateReturnExpressionTypes(<Block>func.body, contextualMapper);
types = checkAndAggregateReturnExpressionTypes(<Block>func.body, contextualMapper, isAsync);
if (types.length === 0) {
return voidType;
}
if (isAsync) {
// For an async function, the return type will not be void, but rather a Promise for void.
let promiseType = createPromiseType(voidType);
if (promiseType === emptyObjectType) {
error(func, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
return unknownType;
}
return promiseType;
}
else {
return voidType;
}
}
}
// When yield/return statements are contextually typed we allow the return type to be a union type.
// Otherwise we require the yield/return expressions to have a best common supertype.
type = contextualSignature ? getUnionType(types) : getCommonSupertype(types);
@ -8615,7 +8686,23 @@ namespace ts {
if (!contextualSignature) {
reportErrorsFromWidening(func, type);
}
return getWidenedType(type);
let widenedType = getWidenedType(type);
if (isAsync) {
// 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.
let promiseType = createPromiseType(widenedType);
if (promiseType === emptyObjectType) {
error(func, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
return unknownType;
}
return promiseType;
}
else {
return widenedType;
}
}
function checkAndAggregateYieldOperandTypes(body: Block, contextualMapper?: TypeMapper): Type[] {
@ -8640,13 +8727,21 @@ namespace ts {
return aggregatedTypes;
}
function checkAndAggregateReturnExpressionTypes(body: Block, contextualMapper?: TypeMapper): Type[] {
function checkAndAggregateReturnExpressionTypes(body: Block, contextualMapper?: TypeMapper, isAsync?: boolean): Type[] {
let aggregatedTypes: Type[] = [];
forEachReturnStatement(body, returnStatement => {
let expr = returnStatement.expression;
if (expr) {
let type = checkExpressionCached(expr, contextualMapper);
let type = checkExpressionCached(expr, contextualMapper);
if (isAsync) {
// 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 should be unwrapped to its awaited type, which should be wrapped in
// the native Promise<T> type by the caller.
type = checkAwaitedType(type, body.parent, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
}
if (!contains(aggregatedTypes, type)) {
aggregatedTypes.push(type);
}
@ -8715,6 +8810,12 @@ namespace ts {
if (contextualMapper === identityMapper && isContextSensitive(node)) {
return anyFunctionType;
}
let isAsync = isAsyncFunctionLike(node);
if (isAsync) {
emitAwaiter = true;
}
let links = getNodeLinks(node);
let type = getTypeOfSymbol(node.symbol);
// Check if function expression is contextually typed and assign parameter types if so
@ -8751,8 +8852,20 @@ namespace ts {
function checkFunctionExpressionOrObjectLiteralMethodBody(node: FunctionExpression | MethodDeclaration) {
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
if (node.type && !node.asteriskToken) {
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type));
let isAsync = isAsyncFunctionLike(node);
if (isAsync) {
emitAwaiter = true;
}
let returnType = node.type && getTypeFromTypeNode(node.type);
let promisedType: Type;
if (returnType && isAsync) {
promisedType = checkAsyncFunctionReturnType(node);
}
if (returnType && !node.asteriskToken) {
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, isAsync ? promisedType : returnType);
}
if (node.body) {
@ -8769,10 +8882,22 @@ namespace ts {
checkSourceElement(node.body);
}
else {
// 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 we
// should not be checking assignability of a promise to the return type. Instead, we need to
// check assignability of the awaited type of the expression body against the promised type of
// its return type annotation.
let exprType = checkExpression(<Expression>node.body);
if (node.type) {
checkTypeAssignableTo(exprType, getTypeFromTypeNode(node.type), node.body, /*headMessage*/ undefined);
if (returnType) {
if (isAsync) {
let awaitedType = checkAwaitedType(exprType, node.body, Diagnostics.Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member);
checkTypeAssignableTo(awaitedType, promisedType, node.body);
}
else {
checkTypeAssignableTo(exprType, returnType, node.body);
}
}
checkFunctionAndClassExpressionBodies(node.body);
}
}
@ -8879,6 +9004,22 @@ namespace ts {
return undefinedType;
}
function checkAwaitExpression(node: AwaitExpression): Type {
// Grammar checking
if (produceDiagnostics) {
if (!(node.parserContextFlags & ParserContextFlags.Await)) {
grammarErrorOnFirstToken(node, Diagnostics.await_expression_is_only_allowed_within_an_async_function);
}
if (isInParameterInitializerBeforeContainingFunction(node)) {
error(node, Diagnostics.await_expressions_cannot_be_used_in_a_parameter_initializer);
}
}
let operandType = checkExpression(node.expression);
return checkAwaitedType(operandType, node);
}
function checkPrefixUnaryExpression(node: PrefixUnaryExpression): Type {
let operandType = checkExpression(node.operand);
switch (node.operator) {
@ -9284,8 +9425,14 @@ namespace ts {
function checkYieldExpression(node: YieldExpression): Type {
// Grammar checking
if (!(node.parserContextFlags & ParserContextFlags.Yield) || isYieldExpressionInClass(node)) {
grammarErrorOnFirstToken(node, Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
if (produceDiagnostics) {
if (!(node.parserContextFlags & ParserContextFlags.Yield) || isYieldExpressionInClass(node)) {
grammarErrorOnFirstToken(node, Diagnostics.A_yield_expression_is_only_allowed_in_a_generator_body);
}
if (isInParameterInitializerBeforeContainingFunction(node)) {
error(node, Diagnostics.yield_expressions_cannot_be_used_in_a_parameter_initializer);
}
}
if (node.expression) {
@ -9345,7 +9492,7 @@ namespace ts {
node.contextualType = saveContextualType;
return result;
}
function checkExpressionCached(node: Expression, contextualMapper?: TypeMapper): Type {
let links = getNodeLinks(node);
if (!links.resolvedType) {
@ -9488,6 +9635,8 @@ namespace ts {
return checkDeleteExpression(<DeleteExpression>node);
case SyntaxKind.VoidExpression:
return checkVoidExpression(<VoidExpression>node);
case SyntaxKind.AwaitExpression:
return checkAwaitExpression(<AwaitExpression>node);
case SyntaxKind.PrefixUnaryExpression:
return checkPrefixUnaryExpression(<PrefixUnaryExpression>node);
case SyntaxKind.PostfixUnaryExpression:
@ -10297,6 +10446,260 @@ namespace ts {
}
}
function checkNonThenableType(type: Type, location?: Node, message?: DiagnosticMessage) {
if (!(type.flags & TypeFlags.Any) && isTypeAssignableTo(type, getGlobalThenableType())) {
if (location) {
if (!message) {
message = Diagnostics.Operand_for_await_does_not_have_a_valid_callable_then_member;
}
error(location, message);
}
return unknownType;
}
return type;
}
/**
* Gets the "promised type" of a promise.
* @param type The type of the promise.
* @remarks The "promised type" of a type is the type of the "value" parameter of the "onfulfilled" callback.
*/
function getPromisedType(promise: Type): Type {
//
// { // promise
// then( // thenFunction
// onfulfilled: ( // onfulfilledParameterType
// value: T // valueParameterType
// ) => any
// ): any;
// }
//
if (promise.flags & TypeFlags.Any) {
return undefined;
}
if ((promise.flags & TypeFlags.Reference) && (<GenericType>promise).target === tryGetGlobalPromiseType()) {
return (<GenericType>promise).typeArguments[0];
}
let globalPromiseLikeType = getInstantiatedGlobalPromiseLikeType();
if (globalPromiseLikeType === emptyObjectType || !isTypeAssignableTo(promise, globalPromiseLikeType)) {
return undefined;
}
let thenFunction = getTypeOfPropertyOfType(promise, "then");
if (thenFunction && (thenFunction.flags & TypeFlags.Any)) {
return undefined;
}
let thenSignatures = thenFunction ? getSignaturesOfType(thenFunction, SignatureKind.Call) : emptyArray;
if (thenSignatures.length === 0) {
return undefined;
}
let onfulfilledParameterType = getUnionType(map(thenSignatures, getTypeOfFirstParameterOfSignature));
if (onfulfilledParameterType.flags & TypeFlags.Any) {
return undefined;
}
let onfulfilledParameterSignatures = getSignaturesOfType(onfulfilledParameterType, SignatureKind.Call);
if (onfulfilledParameterSignatures.length === 0) {
return undefined;
}
let valueParameterType = getUnionType(map(onfulfilledParameterSignatures, getTypeOfFirstParameterOfSignature));
return valueParameterType;
}
function getTypeOfFirstParameterOfSignature(signature: Signature) {
return getTypeAtPosition(signature, 0);
}
/**
* Gets the "awaited type" of a type.
* @param type The type to await.
* @remarks The "awaited type" of an expression is its "promised type" if the expression is a
* Promise-like type; otherwise, it is the type of the expression. This is used to reflect
* The runtime behavior of the `await` keyword.
*/
function getAwaitedType(type: Type) {
return checkAwaitedType(type, /*location*/ undefined, /*message*/ undefined);
}
function checkAwaitedType(type: Type, location?: Node, message?: DiagnosticMessage) {
return checkAwaitedTypeWorker(type);
function checkAwaitedTypeWorker(type: Type): Type {
if (type.flags & TypeFlags.Union) {
let types: Type[] = [];
for (let constituentType of (<UnionType>type).types) {
types.push(checkAwaitedTypeWorker(constituentType));
}
return getUnionType(types);
}
else {
let promisedType = getPromisedType(type);
if (promisedType === undefined) {
// The type was not a PromiseLike, so it could not be unwrapped any further.
// As long as the type does not have a callable "then" property, it is
// safe to return the type; otherwise, an error will have been reported in
// the call to checkNonThenableType and we will return unknownType.
//
// An example of a non-promise "thenable" might be:
//
// await { then(): void {} }
//
// The "thenable" does not match the minimal definition for a PromiseLike. When
// a Promise/A+-compatible or ES6 promise tries to adopt this value, the promise
// will never settle. We treat this as an error to help flag an early indicator
// of a runtime problem. If the user wants to return this value from an async
// function, they would need to wrap it in some other value. If they want it to
// be treated as a promise, they can cast to <any>.
return checkNonThenableType(type, location, message);
}
else {
if (type.id === promisedType.id || awaitedTypeStack.indexOf(promisedType.id) >= 0) {
// We have a bad actor in the form of a promise whose promised type is
// the same promise type, or a mutually recursive promise. Return the
// unknown type as we cannot guess the shape. If this were the actual
// case in the JavaScript, this Promise would never resolve.
//
// An example of a bad actor with a singly-recursive promise type might
// be:
//
// interface BadPromise {
// then(
// onfulfilled: (value: BadPromise) => any,
// onrejected: (error: any) => any): BadPromise;
// }
//
// The above interface will pass the PromiseLike check, and return a
// promised type of `BadPromise`. Since this is a self reference, we
// don't want to keep recursing ad infinitum.
//
// An example of a bad actor in the form of a mutually-recursive
// promise type might be:
//
// interface BadPromiseA {
// then(
// onfulfilled: (value: BadPromiseB) => any,
// onrejected: (error: any) => any): BadPromiseB;
// }
//
// interface BadPromiseB {
// then(
// onfulfilled: (value: BadPromiseA) => any,
// onrejected: (error: any) => any): BadPromiseA;
// }
//
if (location) {
error(
location,
Diagnostics._0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method,
symbolToString(type.symbol));
}
return unknownType;
}
// Keep track of the type we're about to unwrap to avoid bad recursive promise types.
// See the comments above for more information.
awaitedTypeStack.push(type.id);
let awaitedType = checkAwaitedTypeWorker(promisedType);
awaitedTypeStack.pop();
return awaitedType;
}
}
}
}
/**
* Checks the return type of an async function to ensure it is a compatible
* Promise implementation.
* @param node The signature to check
* @param returnType The return type for the function
* @remarks
* This checks that an async function has a valid Promise-compatible return type,
* and returns the *awaited type* of the promise. An async function has a valid
* Promise-compatible return type if the resolved value of the return type has a
* construct signature that takes in an `initializer` function that in turn supplies
* a `resolve` function as one of its arguments and results in an object with a
* callable `then` signature.
*/
function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
let globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
if (globalPromiseConstructorLikeType === emptyObjectType) {
// If we couldn't resolve the global PromiseConstructorLike type we cannot verify
// compatibility with __awaiter.
return unknownType;
}
// As part of our emit for an async function, we will need to emit the entity name of
// the return type annotation as an expression. To meet the necessary runtime semantics
// for __awaiter, we must also check that the type of the declaration (e.g. the static
// side or "constructor" of the promise type) is compatible `PromiseConstructorLike`.
//
// An example might be (from lib.es6.d.ts):
//
// interface Promise<T> { ... }
// interface PromiseConstructor {
// new <T>(...): Promise<T>;
// }
// declare var Promise: PromiseConstructor;
//
// When an async function declares a return type annotation of `Promise<T>`, we
// need to get the type of the `Promise` variable declaration above, which would
// be `PromiseConstructor`.
//
// The same case applies to a class:
//
// declare class Promise<T> {
// constructor(...);
// then<U>(...): Promise<U>;
// }
//
// When we get the type of the `Promise` symbol here, we get the type of the static
// side of the `Promise` class, which would be `{ new <T>(...): Promise<T> }`.
let promiseType = getTypeFromTypeNode(node.type);
if (promiseType === unknownType && compilerOptions.isolatedModules) {
// If we are compiling with isolatedModules, we may not be able to resolve the
// type as a value. As such, we will just return unknownType;
return unknownType;
}
let promiseConstructor = getMergedSymbol(promiseType.symbol);
if (!promiseConstructor || !symbolIsValue(promiseConstructor)) {
error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeToString(promiseType));
return unknownType
}
// Validate the promise constructor type.
let promiseConstructorType = getTypeOfSymbol(promiseConstructor);
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
return unknownType;
}
// Verify there is no local declaration that could collide with the promise constructor.
let promiseName = getEntityNameFromTypeNode(node.type);
let root = getFirstIdentifier(promiseName);
let rootSymbol = getSymbol(node.locals, root.text, SymbolFlags.Value);
if (rootSymbol) {
error(rootSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
root.text,
getFullyQualifiedName(promiseConstructor));
return unknownType;
}
// Get and return the awaited type of the return type.
return checkAwaitedType(promiseType, node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
}
/** Check a decorator */
function checkDecorator(node: Decorator): void {
let signature = getResolvedSignature(node);
@ -10456,6 +10859,14 @@ namespace ts {
function checkFunctionLikeDeclaration(node: FunctionLikeDeclaration): void {
checkDecorators(node);
checkSignatureDeclaration(node);
let isAsync = isAsyncFunctionLike(node);
if (isAsync) {
if (!compilerOptions.experimentalAsyncFunctions) {
error(node, Diagnostics.Experimental_support_for_async_functions_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalAsyncFunctions_to_remove_this_warning);
}
emitAwaiter = true;
}
// Do not use hasDynamicName here, because that returns false for well known symbols.
// We want to perform checkComputedPropertyName for all computed properties, including
@ -10490,7 +10901,13 @@ namespace ts {
checkSourceElement(node.body);
if (node.type && !isAccessor(node.kind) && !node.asteriskToken) {
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, getTypeFromTypeNode(node.type));
let returnType = getTypeFromTypeNode(node.type);
let promisedType: Type;
if (isAsync) {
promisedType = checkAsyncFunctionReturnType(node);
}
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, isAsync ? promisedType : returnType);
}
if (produceDiagnostics && !node.type) {
@ -10701,7 +11118,7 @@ namespace ts {
}
}
}
// Check that a parameter initializer contains no references to parameters declared to the right of itself
function checkParameterInitializer(node: VariableLikeDeclaration): void {
if (getRootDeclaration(node).kind !== SyntaxKind.Parameter) {
@ -10820,7 +11237,14 @@ namespace ts {
function checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node: Node) {
if (node.modifiers) {
if (inBlockOrObjectLiteralExpression(node)) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
if (isAsyncFunctionLike(node)) {
if (node.modifiers.length > 1) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
}
}
else {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
}
}
}
}
@ -10833,6 +11257,8 @@ namespace ts {
node = node.parent;
}
return false;
}
function checkExpressionStatement(node: ExpressionStatement) {
@ -11265,14 +11691,26 @@ namespace ts {
}
}
else if (func.type || isGetAccessorWithAnnotatatedSetAccessor(func) || signature.typePredicate) {
checkTypeAssignableTo(exprType, returnType, node.expression, /*headMessage*/ undefined);
if (isAsyncFunctionLike(func)) {
let promisedType = getPromisedType(returnType);
let awaitedType = checkAwaitedType(exprType, node.expression, Diagnostics.Return_expression_in_async_function_does_not_have_a_valid_callable_then_member);
checkTypeAssignableTo(awaitedType, promisedType, node.expression);
}
else {
checkTypeAssignableTo(exprType, returnType, node.expression);
}
}
}
}
}
function checkWithStatement(node: WithStatement) {
checkGrammarStatementInAmbientContext(node);
// Grammar checking for withStatement
if (!checkGrammarStatementInAmbientContext(node)) {
if (node.parserContextFlags & ParserContextFlags.Await) {
grammarErrorOnFirstToken(node, Diagnostics.with_statements_are_not_allowed_in_an_async_function_block);
}
}
checkExpression(node.expression);
error(node.expression, Diagnostics.All_symbols_within_a_with_block_will_be_resolved_to_any);
@ -12518,12 +12956,14 @@ namespace ts {
case SyntaxKind.ParenthesizedExpression:
case SyntaxKind.TypeOfExpression:
case SyntaxKind.VoidExpression:
case SyntaxKind.AwaitExpression:
case SyntaxKind.DeleteExpression:
case SyntaxKind.PrefixUnaryExpression:
case SyntaxKind.PostfixUnaryExpression:
case SyntaxKind.BinaryExpression:
case SyntaxKind.ConditionalExpression:
case SyntaxKind.SpreadElementExpression:
case SyntaxKind.YieldExpression:
case SyntaxKind.Block:
case SyntaxKind.ModuleBlock:
case SyntaxKind.VariableStatement:
@ -12600,7 +13040,7 @@ namespace ts {
forEach(potentialThisCollisions, checkIfThisIsCapturedInEnclosingScope);
potentialThisCollisions.length = 0;
}
if (emitExtends) {
links.flags |= NodeCheckFlags.EmitExtends;
}
@ -12612,6 +13052,14 @@ namespace ts {
if (emitParam) {
links.flags |= NodeCheckFlags.EmitParam;
}
if (emitAwaiter) {
links.flags |= NodeCheckFlags.EmitAwaiter;
}
if (emitGenerator || (emitAwaiter && languageVersion < ScriptTarget.ES6)) {
links.flags |= NodeCheckFlags.EmitGenerator;
}
links.flags |= NodeCheckFlags.TypeChecked;
}
@ -13546,6 +13994,13 @@ namespace ts {
getGlobalMethodDecoratorType = memoize(() => getGlobalType("MethodDecorator"));
getGlobalParameterDecoratorType = memoize(() => getGlobalType("ParameterDecorator"));
getGlobalTypedPropertyDescriptorType = memoize(() => getGlobalType("TypedPropertyDescriptor", /*arity*/ 1));
getGlobalPromiseType = memoize(() => getGlobalType("Promise", /*arity*/ 1));
tryGetGlobalPromiseType = memoize(() => getGlobalSymbol("Promise", SymbolFlags.Type, /*diagnostic*/ undefined) && getGlobalPromiseType());
getGlobalPromiseLikeType = memoize(() => getGlobalType("PromiseLike", /*arity*/ 1));
getInstantiatedGlobalPromiseLikeType = memoize(createInstantiatedPromiseLikeType);
getGlobalPromiseConstructorSymbol = memoize(() => getGlobalValueSymbol("Promise"));
getGlobalPromiseConstructorLikeType = memoize(() => getGlobalType("PromiseConstructorLike"));
getGlobalThenableType = memoize(createThenableType);
// If we're in ES6 mode, load the TemplateStringsArray.
// Otherwise, default to 'unknown' for the purposes of type checking in LS scenarios.
@ -13572,6 +14027,28 @@ namespace ts {
anyArrayType = createArrayType(anyType);
}
function createInstantiatedPromiseLikeType(): ObjectType {
let promiseLikeType = getGlobalPromiseLikeType();
if (promiseLikeType !== emptyObjectType) {
return createTypeReference(<GenericType>promiseLikeType, [anyType]);
}
return emptyObjectType;
}
function createThenableType() {
// build the thenable type that is used to verify against a non-promise "thenable" operand to `await`.
let thenPropertySymbol = createSymbol(SymbolFlags.Transient | SymbolFlags.Property, "then");
getSymbolLinks(thenPropertySymbol).type = globalFunctionType;
let thenableType = <ResolvedType>createObjectType(TypeFlags.Anonymous);
thenableType.properties = [thenPropertySymbol];
thenableType.members = createSymbolTable(thenableType.properties);
thenableType.callSignatures = [];
thenableType.constructSignatures = [];
return thenableType;
}
// GRAMMAR CHECKING
function checkGrammarDecorators(node: Node): boolean {
@ -13610,10 +14087,15 @@ namespace ts {
case SyntaxKind.ExportAssignment:
case SyntaxKind.Parameter:
break;
case SyntaxKind.FunctionDeclaration:
if (node.modifiers && (node.modifiers.length > 1 || node.modifiers[0].kind !== SyntaxKind.AsyncKeyword) &&
node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
}
break;
case SyntaxKind.ClassDeclaration:
case SyntaxKind.InterfaceDeclaration:
case SyntaxKind.VariableStatement:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.TypeAliasDeclaration:
if (node.modifiers && node.parent.kind !== SyntaxKind.ModuleBlock && node.parent.kind !== SyntaxKind.SourceFile) {
return grammarErrorOnFirstToken(node, Diagnostics.Modifiers_cannot_appear_here);
@ -13633,7 +14115,7 @@ namespace ts {
return;
}
let lastStatic: Node, lastPrivate: Node, lastProtected: Node, lastDeclare: Node;
let lastStatic: Node, lastPrivate: Node, lastProtected: Node, lastDeclare: Node, lastAsync: Node;
let flags = 0;
for (let modifier of node.modifiers) {
switch (modifier.kind) {
@ -13659,6 +14141,9 @@ namespace ts {
else if (flags & NodeFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "static");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, text, "async");
}
else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_element, text);
}
@ -13669,6 +14154,9 @@ namespace ts {
if (flags & NodeFlags.Static) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "static");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "static", "async");
}
else if (node.parent.kind === SyntaxKind.ModuleBlock || node.parent.kind === SyntaxKind.SourceFile) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_module_element, "static");
}
@ -13686,6 +14174,9 @@ namespace ts {
else if (flags & NodeFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "declare");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_must_precede_1_modifier, "export", "async");
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_class_element, "export");
}
@ -13699,6 +14190,9 @@ namespace ts {
if (flags & NodeFlags.Ambient) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.parent.kind === SyntaxKind.ClassDeclaration) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_class_element, "declare");
}
@ -13711,6 +14205,20 @@ namespace ts {
flags |= NodeFlags.Ambient;
lastDeclare = modifier
break;
case SyntaxKind.AsyncKeyword:
if (flags & NodeFlags.Async) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "async");
}
else if (flags & NodeFlags.Ambient || isInAmbientContext(node.parent)) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_in_an_ambient_context, "async");
}
else if (node.kind === SyntaxKind.Parameter) {
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_appear_on_a_parameter, "async");
}
flags |= NodeFlags.Async;
lastAsync = modifier;
break;
}
}
@ -13724,13 +14232,39 @@ namespace ts {
else if (flags & NodeFlags.Private) {
return grammarErrorOnNode(lastPrivate, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "private");
}
else if (flags & NodeFlags.Async) {
return grammarErrorOnNode(lastAsync, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
}
return;
}
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & NodeFlags.Ambient) {
return grammarErrorOnNode(lastDeclare, Diagnostics.A_declare_modifier_cannot_be_used_with_an_import_declaration, "declare");
return grammarErrorOnNode(lastDeclare, Diagnostics.A_0_modifier_cannot_be_used_with_an_import_declaration, "declare");
}
else if (node.kind === SyntaxKind.Parameter && (flags & NodeFlags.AccessibilityModifier) && isBindingPattern((<ParameterDeclaration>node).name)) {
return grammarErrorOnNode(node, Diagnostics.A_parameter_property_may_not_be_a_binding_pattern);
}
if (flags & NodeFlags.Async) {
return checkGrammarAsyncModifier(node, lastAsync);
}
}
function checkGrammarAsyncModifier(node: Node, asyncModifier: Node): boolean {
if (languageVersion < ScriptTarget.ES6) {
return grammarErrorOnNode(asyncModifier, Diagnostics.Async_functions_are_only_available_when_targeting_ECMAScript_6_and_higher);
}
switch (node.kind) {
case SyntaxKind.MethodDeclaration:
case SyntaxKind.FunctionDeclaration:
case SyntaxKind.FunctionExpression:
case SyntaxKind.ArrowFunction:
if (!(<FunctionLikeDeclaration>node).asteriskToken) {
return false;
}
break;
}
return grammarErrorOnNode(asyncModifier, Diagnostics._0_modifier_cannot_be_used_here, "async");
}
function checkGrammarForDisallowedTrailingComma(list: NodeArray<Node>): boolean {

View File

@ -203,6 +203,11 @@ namespace ts {
type: "boolean",
description: Diagnostics.Watch_input_files,
},
{
name: "experimentalAsyncFunctions",
type: "boolean",
description: Diagnostics.Enables_experimental_support_for_ES7_async_functions
},
{
name: "experimentalDecorators",
type: "boolean",

View File

@ -29,7 +29,12 @@ namespace ts {
Statements_are_not_allowed_in_ambient_contexts: { code: 1036, category: DiagnosticCategory.Error, key: "Statements are not allowed in ambient contexts." },
A_declare_modifier_cannot_be_used_in_an_already_ambient_context: { code: 1038, category: DiagnosticCategory.Error, key: "A 'declare' modifier cannot be used in an already ambient context." },
Initializers_are_not_allowed_in_ambient_contexts: { code: 1039, category: DiagnosticCategory.Error, key: "Initializers are not allowed in ambient contexts." },
_0_modifier_cannot_be_used_in_an_ambient_context: { code: 1040, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used in an ambient context." },
_0_modifier_cannot_be_used_with_a_class_declaration: { code: 1041, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used with a class declaration." },
_0_modifier_cannot_be_used_here: { code: 1042, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used here." },
_0_modifier_cannot_appear_on_a_data_property: { code: 1043, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot appear on a data property." },
_0_modifier_cannot_appear_on_a_module_element: { code: 1044, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot appear on a module element." },
A_0_modifier_cannot_be_used_with_an_interface_declaration: { code: 1045, category: DiagnosticCategory.Error, key: "A '{0}' modifier cannot be used with an interface declaration." },
A_declare_modifier_is_required_for_a_top_level_declaration_in_a_d_ts_file: { code: 1046, category: DiagnosticCategory.Error, key: "A 'declare' modifier is required for a top level declaration in a .d.ts file." },
A_rest_parameter_cannot_be_optional: { code: 1047, category: DiagnosticCategory.Error, key: "A rest parameter cannot be optional." },
A_rest_parameter_cannot_have_an_initializer: { code: 1048, category: DiagnosticCategory.Error, key: "A rest parameter cannot have an initializer." },
@ -38,12 +43,18 @@ namespace ts {
A_set_accessor_parameter_cannot_have_an_initializer: { code: 1052, category: DiagnosticCategory.Error, key: "A 'set' accessor parameter cannot have an initializer." },
A_set_accessor_cannot_have_rest_parameter: { code: 1053, category: DiagnosticCategory.Error, key: "A 'set' accessor cannot have rest parameter." },
A_get_accessor_cannot_have_parameters: { code: 1054, category: DiagnosticCategory.Error, key: "A 'get' accessor cannot have parameters." },
Type_0_is_not_a_valid_async_function_return_type: { code: 1055, category: DiagnosticCategory.Error, key: "Type '{0}' is not a valid async function return type." },
Accessors_are_only_available_when_targeting_ECMAScript_5_and_higher: { code: 1056, category: DiagnosticCategory.Error, key: "Accessors are only available when targeting ECMAScript 5 and higher." },
An_async_function_or_method_must_have_a_valid_awaitable_return_type: { code: 1057, category: DiagnosticCategory.Error, key: "An async function or method must have a valid awaitable return type." },
Operand_for_await_does_not_have_a_valid_callable_then_member: { code: 1058, category: DiagnosticCategory.Error, key: "Operand for 'await' does not have a valid callable 'then' member." },
Return_expression_in_async_function_does_not_have_a_valid_callable_then_member: { code: 1059, category: DiagnosticCategory.Error, key: "Return expression in async function does not have a valid callable 'then' member." },
Expression_body_for_async_arrow_function_does_not_have_a_valid_callable_then_member: { code: 1060, category: DiagnosticCategory.Error, key: "Expression body for async arrow function does not have a valid callable 'then' member." },
Enum_member_must_have_initializer: { code: 1061, category: DiagnosticCategory.Error, key: "Enum member must have initializer." },
_0_is_referenced_directly_or_indirectly_in_the_fulfillment_callback_of_its_own_then_method: { code: 1062, category: DiagnosticCategory.Error, key: "{0} is referenced directly or indirectly in the fulfillment callback of its own 'then' method." },
An_export_assignment_cannot_be_used_in_a_namespace: { code: 1063, category: DiagnosticCategory.Error, key: "An export assignment cannot be used in a namespace." },
Ambient_enum_elements_can_only_have_integer_literal_initializers: { code: 1066, category: DiagnosticCategory.Error, key: "Ambient enum elements can only have integer literal initializers." },
Unexpected_token_A_constructor_method_accessor_or_property_was_expected: { code: 1068, category: DiagnosticCategory.Error, key: "Unexpected token. A constructor, method, accessor, or property was expected." },
A_declare_modifier_cannot_be_used_with_an_import_declaration: { code: 1079, category: DiagnosticCategory.Error, key: "A 'declare' modifier cannot be used with an import declaration." },
A_0_modifier_cannot_be_used_with_an_import_declaration: { code: 1079, category: DiagnosticCategory.Error, key: "A '{0}' modifier cannot be used with an import declaration." },
Invalid_reference_directive_syntax: { code: 1084, category: DiagnosticCategory.Error, key: "Invalid 'reference' directive syntax." },
Octal_literals_are_not_available_when_targeting_ECMAScript_5_and_higher: { code: 1085, category: DiagnosticCategory.Error, key: "Octal literals are not available when targeting ECMAScript 5 and higher." },
An_accessor_cannot_be_declared_in_an_ambient_context: { code: 1086, category: DiagnosticCategory.Error, key: "An accessor cannot be declared in an ambient context." },
@ -179,6 +190,10 @@ namespace ts {
An_export_declaration_can_only_be_used_in_a_module: { code: 1233, category: DiagnosticCategory.Error, key: "An export declaration can only be used in a module." },
An_ambient_module_declaration_is_only_allowed_at_the_top_level_in_a_file: { code: 1234, category: DiagnosticCategory.Error, key: "An ambient module declaration is only allowed at the top level in a file." },
A_namespace_declaration_is_only_allowed_in_a_namespace_or_module: { code: 1235, category: DiagnosticCategory.Error, key: "A namespace declaration is only allowed in a namespace or module." },
Experimental_support_for_async_functions_is_a_feature_that_is_subject_to_change_in_a_future_release_Specify_experimentalAsyncFunctions_to_remove_this_warning: { code: 1236, category: DiagnosticCategory.Error, key: "Experimental support for async functions is a feature that is subject to change in a future release. Specify '--experimentalAsyncFunctions' to remove this warning." },
with_statements_are_not_allowed_in_an_async_function_block: { code: 1300, category: DiagnosticCategory.Error, key: "'with' statements are not allowed in an async function block." },
await_expression_is_only_allowed_within_an_async_function: { code: 1308, category: DiagnosticCategory.Error, key: "'await' expression is only allowed within an async function." },
Async_functions_are_only_available_when_targeting_ECMAScript_6_and_higher: { code: 1311, category: DiagnosticCategory.Error, key: "Async functions are only available when targeting ECMAScript 6 and higher." },
The_return_type_of_a_property_decorator_function_must_be_either_void_or_any: { code: 1236, category: DiagnosticCategory.Error, key: "The return type of a property decorator function must be either 'void' or 'any'." },
The_return_type_of_a_parameter_decorator_function_must_be_either_void_or_any: { code: 1237, category: DiagnosticCategory.Error, key: "The return type of a parameter decorator function must be either 'void' or 'any'." },
Unable_to_resolve_signature_of_class_decorator_when_called_as_an_expression: { code: 1238, category: DiagnosticCategory.Error, key: "Unable to resolve signature of class decorator when called as an expression." },
@ -382,6 +397,11 @@ namespace ts {
No_base_constructor_has_the_specified_number_of_type_arguments: { code: 2508, category: DiagnosticCategory.Error, key: "No base constructor has the specified number of type arguments." },
Base_constructor_return_type_0_is_not_a_class_or_interface_type: { code: 2509, category: DiagnosticCategory.Error, key: "Base constructor return type '{0}' is not a class or interface type." },
Base_constructors_must_all_have_the_same_return_type: { code: 2510, category: DiagnosticCategory.Error, key: "Base constructors must all have the same return type." },
Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." },
Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." },
The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_function_expression: { code: 2522, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression." },
yield_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2523, category: DiagnosticCategory.Error, key: "'yield' expressions cannot be used in a parameter initializer." },
await_expressions_cannot_be_used_in_a_parameter_initializer: { code: 2524, category: DiagnosticCategory.Error, key: "'await' expressions cannot be used in a parameter initializer." },
JSX_element_attributes_type_0_must_be_an_object_type: { code: 2600, category: DiagnosticCategory.Error, key: "JSX element attributes type '{0}' must be an object type." },
The_return_type_of_a_JSX_element_constructor_must_return_an_object_type: { code: 2601, category: DiagnosticCategory.Error, key: "The return type of a JSX element constructor must return an object type." },
JSX_element_implicitly_has_type_any_because_the_global_type_JSX_Element_does_not_exist: { code: 2602, category: DiagnosticCategory.Error, key: "JSX element implicitly has type 'any' because the global type 'JSX.Element' does not exist." },
@ -538,6 +558,8 @@ namespace ts {
Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified: { code: 6064, category: DiagnosticCategory.Error, key: "Option 'experimentalDecorators' must also be specified when option 'emitDecoratorMetadata' is specified." },
Enables_experimental_support_for_ES7_decorators: { code: 6065, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 decorators." },
Enables_experimental_support_for_emitting_type_metadata_for_decorators: { code: 6066, category: DiagnosticCategory.Message, key: "Enables experimental support for emitting type metadata for decorators." },
Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower: { code: 6067, category: DiagnosticCategory.Message, key: "Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower." },
Enables_experimental_support_for_ES7_async_functions: { code: 6068, category: DiagnosticCategory.Message, key: "Enables experimental support for ES7 async functions." },
Variable_0_implicitly_has_an_1_type: { code: 7005, category: DiagnosticCategory.Error, key: "Variable '{0}' implicitly has an '{1}' type." },
Parameter_0_implicitly_has_an_1_type: { code: 7006, category: DiagnosticCategory.Error, key: "Parameter '{0}' implicitly has an '{1}' type." },
Member_0_implicitly_has_an_1_type: { code: 7008, category: DiagnosticCategory.Error, key: "Member '{0}' implicitly has an '{1}' type." },

View File

@ -103,10 +103,30 @@
"category": "Error",
"code": 1039
},
"'{0}' modifier cannot be used in an ambient context.": {
"category": "Error",
"code": 1040
},
"'{0}' modifier cannot be used with a class declaration.": {
"category": "Error",
"code": 1041
},
"'{0}' modifier cannot be used here.": {
"category": "Error",
"code": 1042
},
"'{0}' modifier cannot appear on a data property.": {
"category": "Error",
"code": 1043
},
"'{0}' modifier cannot appear on a module element.": {
"category": "Error",
"code": 1044
},
"A '{0}' modifier cannot be used with an interface declaration.": {
"category": "Error",
"code": 1045
},
"A 'declare' modifier is required for a top level declaration in a .d.ts file.": {
"category": "Error",
"code": 1046
@ -139,14 +159,38 @@
"category": "Error",
"code": 1054
},
"Type '{0}' is not a valid async function return type.": {
"category": "Error",
"code": 1055
},
"Accessors are only available when targeting ECMAScript 5 and higher.": {
"category": "Error",
"code": 1056
},
"An async function or method must have a valid awaitable return type.": {
"category": "Error",
"code": 1057
},
"Operand for 'await' does not have a valid callable 'then' member.": {
"category": "Error",
"code": 1058
},
"Return expression in async function does not have a valid callable 'then' member.": {
"category": "Error",
"code": 1059
},
"Expression body for async arrow function does not have a valid callable 'then' member.": {
"category": "Error",
"code": 1060
},
"Enum member must have initializer.": {
"category": "Error",
"code": 1061
},
"{0} is referenced directly or indirectly in the fulfillment callback of its own 'then' method.": {
"category": "Error",
"code": 1062
},
"An export assignment cannot be used in a namespace.": {
"category": "Error",
"code": 1063
@ -159,7 +203,7 @@
"category": "Error",
"code": 1068
},
"A 'declare' modifier cannot be used with an import declaration.": {
"A '{0}' modifier cannot be used with an import declaration.": {
"category": "Error",
"code": 1079
},
@ -703,8 +747,25 @@
"category": "Error",
"code": 1235
},
"Experimental support for async functions is a feature that is subject to change in a future release. Specify '--experimentalAsyncFunctions' to remove this warning.": {
"category": "Error",
"code": 1236
},
"'with' statements are not allowed in an async function block.": {
"category": "Error",
"code": 1300
},
"'await' expression is only allowed within an async function.": {
"category": "Error",
"code": 1308
},
"Async functions are only available when targeting ECMAScript 6 and higher.": {
"category": "Error",
"code": 1311
},
"The return type of a property decorator function must be either 'void' or 'any'.": {
"category": "Error",
"code": 1236
@ -1519,6 +1580,27 @@
"code": 2510
},
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
"category": "Error",
"code": 2520
},
"Expression resolves to variable declaration '{0}' that compiler uses to support async functions.": {
"category": "Error",
"code": 2521
},
"The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression.": {
"category": "Error",
"code": 2522
},
"'yield' expressions cannot be used in a parameter initializer.": {
"category": "Error",
"code": 2523
},
"'await' expressions cannot be used in a parameter initializer.": {
"category": "Error",
"code": 2524
},
"JSX element attributes type '{0}' must be an object type.": {
"category": "Error",
"code": 2600
@ -2145,6 +2227,14 @@
"category": "Message",
"code": 6066
},
"Option 'experimentalAsyncFunctions' cannot be specified when targeting ES5 or lower.": {
"category": "Message",
"code": 6067
},
"Enables experimental support for ES7 async functions.": {
"category": "Message",
"code": 6068
},
"Variable '{0}' implicitly has an '{1}' type.": {
"category": "Error",

View File

@ -47,6 +47,20 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return function (target, key) { decorator(target, key, paramIndex); }
};`;
const awaiterHelper = `
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
return new Promise(function (resolve, reject) {
generator = generator.call(thisArg, _arguments);
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
function step(verb, value) {
var result = generator[verb](value);
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
}
step("next", void 0);
});
};`;
let compilerOptions = host.getCompilerOptions();
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
@ -115,7 +129,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
let writeLine = writer.writeLine;
let increaseIndent = writer.increaseIndent;
let decreaseIndent = writer.decreaseIndent;
let currentSourceFile: SourceFile;
// name of an exporter function if file is a System external module
// System.register([...], function (<exporter>) {...})
@ -132,6 +146,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
let extendsEmitted = false;
let decorateEmitted = false;
let paramEmitted = false;
let awaiterEmitted = false;
let tempFlags = 0;
let tempVariables: Identifier[];
let tempParameters: Identifier[];
@ -1449,6 +1464,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function emitExpressionIdentifier(node: Identifier) {
if (resolver.getNodeCheckFlags(node) & NodeCheckFlags.LexicalArguments) {
write("_arguments");
return;
}
let container = resolver.getReferencedExportContainer(node);
if (container) {
if (container.kind === SyntaxKind.SourceFile) {
@ -1588,6 +1608,30 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emit(node.expression);
}
}
function emitAwaitExpression(node: AwaitExpression) {
let needsParenthesis = needsParenthesisForAwaitExpressionAsYield(node);
if (needsParenthesis) {
write("(");
}
write(tokenToString(SyntaxKind.YieldKeyword));
write(" ");
emit(node.expression);
if (needsParenthesis) {
write(")");
}
}
function needsParenthesisForAwaitExpressionAsYield(node: AwaitExpression) {
if (node.parent.kind === SyntaxKind.BinaryExpression && !isAssignmentOperator((<BinaryExpression>node.parent).operatorToken.kind)) {
return true;
}
else if (node.parent.kind === SyntaxKind.ConditionalExpression && (<ConditionalExpression>node.parent).condition === node) {
return true;
}
return false;
}
function needsParenthesisForPropertyAccessOrInvocation(node: Expression) {
switch (node.kind) {
@ -3568,8 +3612,149 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
emit(node.parameters[0]);
return;
}
emitSignatureParameters(node);
}
function emitAsyncFunctionBodyForES6(node: FunctionLikeDeclaration) {
let promiseConstructor = getEntityNameFromTypeNode(node.type);
let isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
let hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
let args: string;
// An async function is emit as an outer function that calls an inner
// generator function. To preserve lexical bindings, we pass the current
// `this` and `arguments` objects to `__awaiter`. The generator function
// passed to `__awaiter` is executed inside of the callback to the
// promise constructor.
//
// The emit for an async arrow without a lexical `arguments` binding might be:
//
// // input
// let a = async (b) => { await b; }
//
// // output
// let a = (b) => __awaiter(this, void 0, void 0, function* () {
// yield b;
// });
//
// The emit for an async arrow with a lexical `arguments` binding might be:
//
// // input
// let a = async (b) => { await arguments[0]; }
//
// // output
// let a = (b) => __awaiter(this, arguments, void 0, function* (arguments) {
// yield arguments[0];
// });
//
// The emit for an async function expression without a lexical `arguments` binding
// might be:
//
// // input
// let a = async function (b) {
// await b;
// }
//
// // output
// let a = function (b) {
// return __awaiter(this, void 0, void 0, function* () {
// yield b;
// });
// }
//
// The emit for an async function expression with a lexical `arguments` binding
// might be:
//
// // input
// let a = async function (b) {
// await arguments[0];
// }
//
// // output
// let a = function (b) {
// return __awaiter(this, arguments, void 0, function* (_arguments) {
// yield _arguments[0];
// });
// }
//
// The emit for an async function expression with a lexical `arguments` binding
// and a return type annotation might be:
//
// // input
// let a = async function (b): MyPromise<any> {
// await arguments[0];
// }
//
// // output
// let a = function (b) {
// return __awaiter(this, arguments, MyPromise, function* (_arguments) {
// yield _arguments[0];
// });
// }
//
// If this is not an async arrow, emit the opening brace of the function body
// and the start of the return statement.
if (!isArrowFunction) {
write(" {");
increaseIndent();
writeLine();
write("return");
}
write(" __awaiter(this");
if (hasLexicalArguments) {
write(", arguments");
}
else {
write(", void 0");
}
if (promiseConstructor) {
write(", ");
emitNodeWithoutSourceMap(promiseConstructor);
}
else {
write(", Promise");
}
// Emit the call to __awaiter.
if (hasLexicalArguments) {
write(", function* (_arguments)");
}
else {
write(", function* ()");
}
// Emit the signature and body for the inner generator function.
emitFunctionBody(node);
write(")");
// If this is not an async arrow, emit the closing brace of the outer function body.
if (!isArrowFunction) {
write(";");
decreaseIndent();
writeLine();
write("}");
}
}
function emitFunctionBody(node: FunctionLikeDeclaration) {
if (!node.body) {
// There can be no body when there are parse errors. Just emit an empty block
// in that case.
write(" { }");
}
else {
if (node.body.kind === SyntaxKind.Block) {
emitBlockFunctionBody(node, <Block>node.body);
}
else {
emitExpressionFunctionBody(node, <Expression>node.body);
}
}
}
function emitSignatureAndBody(node: FunctionLikeDeclaration) {
let saveTempFlags = tempFlags;
@ -3587,19 +3772,15 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
else {
emitSignatureParameters(node);
}
if (!node.body) {
// There can be no body when there are parse errors. Just emit an empty block
// in that case.
write(" { }");
}
else if (node.body.kind === SyntaxKind.Block) {
emitBlockFunctionBody(node, <Block>node.body);
let isAsync = isAsyncFunctionLike(node);
if (isAsync && languageVersion === ScriptTarget.ES6) {
emitAsyncFunctionBodyForES6(node);
}
else {
emitExpressionFunctionBody(node, <Expression>node.body);
emitFunctionBody(node);
}
if (!isES6ExportedDeclaration(node)) {
emitExportMemberAssignment(node);
}
@ -3617,7 +3798,7 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
}
function emitExpressionFunctionBody(node: FunctionLikeDeclaration, body: Expression) {
if (languageVersion < ScriptTarget.ES6) {
if (languageVersion < ScriptTarget.ES6 || node.flags & NodeFlags.Async) {
emitDownLevelExpressionFunctionBody(node, body);
return;
}
@ -6064,6 +6245,11 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
writeLines(paramHelper);
paramEmitted = true;
}
if (!awaiterEmitted && resolver.getNodeCheckFlags(node) & NodeCheckFlags.EmitAwaiter) {
writeLines(awaiterHelper);
awaiterEmitted = true;
}
}
if (isExternalModule(node) || compilerOptions.isolatedModules) {
@ -6246,6 +6432,8 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
return emitTypeOfExpression(<TypeOfExpression>node);
case SyntaxKind.VoidExpression:
return emitVoidExpression(<VoidExpression>node);
case SyntaxKind.AwaitExpression:
return emitAwaitExpression(<AwaitExpression>node);
case SyntaxKind.PrefixUnaryExpression:
return emitPrefixUnaryExpression(<PrefixUnaryExpression>node);
case SyntaxKind.PostfixUnaryExpression:

View File

@ -156,6 +156,8 @@ namespace ts {
case SyntaxKind.YieldExpression:
return visitNode(cbNode, (<YieldExpression>node).asteriskToken) ||
visitNode(cbNode, (<YieldExpression>node).expression);
case SyntaxKind.AwaitExpression:
return visitNode(cbNode, (<AwaitExpression>node).expression);
case SyntaxKind.PostfixUnaryExpression:
return visitNode(cbNode, (<PostfixUnaryExpression>node).operand);
case SyntaxKind.BinaryExpression:
@ -679,103 +681,112 @@ namespace ts {
setContextFlag(val, ParserContextFlags.Yield);
}
function setGeneratorParameterContext(val: boolean) {
setContextFlag(val, ParserContextFlags.GeneratorParameter);
}
function setDecoratorContext(val: boolean) {
setContextFlag(val, ParserContextFlags.Decorator);
}
function doOutsideOfContext<T>(flags: ParserContextFlags, func: () => T): T {
let currentContextFlags = contextFlags & flags;
if (currentContextFlags) {
setContextFlag(false, currentContextFlags);
function setAwaitContext(val: boolean) {
setContextFlag(val, ParserContextFlags.Await);
}
function doOutsideOfContext<T>(context: ParserContextFlags, func: () => T): T {
// contextFlagsToClear will contain only the context flags that are
// currently set that we need to temporarily clear
// We don't just blindly reset to the previous flags to ensure
// that we do not mutate cached flags for the incremental
// parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
// HasAggregatedChildData).
let contextFlagsToClear = context & contextFlags;
if (contextFlagsToClear) {
// clear the requested context flags
setContextFlag(false, contextFlagsToClear);
let result = func();
setContextFlag(true, currentContextFlags);
// restore the context flags we just cleared
setContextFlag(true, contextFlagsToClear);
return result;
}
// no need to do anything special as we are not in any of the requested contexts
return func();
}
function allowInAnd<T>(func: () => T): T {
if (contextFlags & ParserContextFlags.DisallowIn) {
setDisallowInContext(false);
function doInsideOfContext<T>(context: ParserContextFlags, func: () => T): T {
// contextFlagsToSet will contain only the context flags that
// are not currently set that we need to temporarily enable.
// We don't just blindly reset to the previous flags to ensure
// that we do not mutate cached flags for the incremental
// parser (ThisNodeHasError, ThisNodeOrAnySubNodesHasError, and
// HasAggregatedChildData).
let contextFlagsToSet = context & ~contextFlags;
if (contextFlagsToSet) {
// set the requested context flags
setContextFlag(true, contextFlagsToSet);
let result = func();
setDisallowInContext(true);
// reset the context flags we just set
setContextFlag(false, contextFlagsToSet);
return result;
}
// no need to do anything special if 'in' is already allowed.
// no need to do anything special as we are already in all of the requested contexts
return func();
}
function allowInAnd<T>(func: () => T): T {
return doOutsideOfContext(ParserContextFlags.DisallowIn, func);
}
function disallowInAnd<T>(func: () => T): T {
if (contextFlags & ParserContextFlags.DisallowIn) {
// no need to do anything special if 'in' is already disallowed.
return func();
}
setDisallowInContext(true);
let result = func();
setDisallowInContext(false);
return result;
return doInsideOfContext(ParserContextFlags.DisallowIn, func);
}
function doInYieldContext<T>(func: () => T): T {
if (contextFlags & ParserContextFlags.Yield) {
// no need to do anything special if we're already in the [Yield] context.
return func();
}
setYieldContext(true);
let result = func();
setYieldContext(false);
return result;
return doInsideOfContext(ParserContextFlags.Yield, func);
}
function doOutsideOfYieldContext<T>(func: () => T): T {
if (contextFlags & ParserContextFlags.Yield) {
setYieldContext(false);
let result = func();
setYieldContext(true);
return result;
}
// no need to do anything special if we're not in the [Yield] context.
return func();
return doOutsideOfContext(ParserContextFlags.Yield, func);
}
function doInDecoratorContext<T>(func: () => T): T {
if (contextFlags & ParserContextFlags.Decorator) {
// no need to do anything special if we're already in the [Decorator] context.
return func();
}
setDecoratorContext(true);
let result = func();
setDecoratorContext(false);
return result;
return doInsideOfContext(ParserContextFlags.Decorator, func);
}
function doInAwaitContext<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.Await, func);
}
function doOutsideOfAwaitContext<T>(func: () => T): T {
return doOutsideOfContext(ParserContextFlags.Await, func);
}
function doInYieldAndAwaitContext<T>(func: () => T): T {
return doInsideOfContext(ParserContextFlags.Yield | ParserContextFlags.Await, func);
}
function doOutsideOfYieldAndAwaitContext<T>(func: () => T): T {
return doOutsideOfContext(ParserContextFlags.Yield | ParserContextFlags.Await, func);
}
function inContext(flags: ParserContextFlags) {
return (contextFlags & flags) !== 0;
}
function inYieldContext() {
return (contextFlags & ParserContextFlags.Yield) !== 0;
}
function inGeneratorParameterContext() {
return (contextFlags & ParserContextFlags.GeneratorParameter) !== 0;
return inContext(ParserContextFlags.Yield);
}
function inDisallowInContext() {
return (contextFlags & ParserContextFlags.DisallowIn) !== 0;
return inContext(ParserContextFlags.DisallowIn);
}
function inDecoratorContext() {
return (contextFlags & ParserContextFlags.Decorator) !== 0;
return inContext(ParserContextFlags.Decorator);
}
function inAwaitContext() {
return inContext(ParserContextFlags.Await);
}
function parseErrorAtCurrentToken(message: DiagnosticMessage, arg0?: any): void {
let start = scanner.getTokenPos();
let length = scanner.getTextPos() - start;
@ -891,6 +902,12 @@ namespace ts {
if (token === SyntaxKind.YieldKeyword && inYieldContext()) {
return false;
}
// If we have a 'await' keyword, and we're in the [Await] context, then 'await' is
// considered a keyword and is not an identifier.
if (token === SyntaxKind.AwaitKeyword && inAwaitContext()) {
return false;
}
return token > SyntaxKind.LastReservedWord;
}
@ -1066,29 +1083,16 @@ namespace ts {
}
function parseComputedPropertyName(): ComputedPropertyName {
// PropertyName[Yield,GeneratorParameter] :
// LiteralPropertyName
// [+GeneratorParameter] ComputedPropertyName
// [~GeneratorParameter] ComputedPropertyName[?Yield]
//
// ComputedPropertyName[Yield] :
// [ AssignmentExpression[In, ?Yield] ]
//
// PropertyName [Yield]:
// LiteralPropertyName
// ComputedPropertyName[?Yield]
let node = <ComputedPropertyName>createNode(SyntaxKind.ComputedPropertyName);
parseExpected(SyntaxKind.OpenBracketToken);
// We parse any expression (including a comma expression). But the grammar
// says that only an assignment expression is allowed, so the grammar checker
// will error if it sees a comma expression.
let yieldContext = inYieldContext();
if (inGeneratorParameterContext()) {
setYieldContext(false);
}
node.expression = allowInAnd(parseExpression);
if (inGeneratorParameterContext()) {
setYieldContext(yieldContext);
}
parseExpected(SyntaxKind.CloseBracketToken);
return finishNode(node);
@ -1097,7 +1101,7 @@ namespace ts {
function parseContextualModifier(t: SyntaxKind): boolean {
return token === t && tryParse(nextTokenCanFollowModifier);
}
function nextTokenCanFollowModifier() {
if (token === SyntaxKind.ConstKeyword) {
// 'const' is only a modifier if followed by 'enum'.
@ -1116,7 +1120,7 @@ namespace ts {
nextToken();
return canFollowModifier();
}
function parseAnyContextualModifier(): boolean {
return isModifier(token) && tryParse(nextTokenCanFollowModifier);
}
@ -1975,14 +1979,13 @@ namespace ts {
function parseParameter(): ParameterDeclaration {
let node = <ParameterDeclaration>createNode(SyntaxKind.Parameter);
node.decorators = parseDecorators();
setModifiers(node, parseModifiers());
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
setModifiers(node, parseModifiers());
// SingleNameBinding[Yield,GeneratorParameter] : See 13.2.3
// [+GeneratorParameter]BindingIdentifier[Yield]Initializer[In]opt
// [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
// FormalParameter [Yield,Await]:
// BindingElement[?Yield,?Await]
node.name = inGeneratorParameterContext() ? doInYieldContext(parseIdentifierOrPattern) : parseIdentifierOrPattern();
node.name = parseIdentifierOrPattern();
if (getFullWidth(node.name) === 0 && node.flags === 0 && isModifier(token)) {
// in cases like
@ -1998,7 +2001,7 @@ namespace ts {
node.questionToken = parseOptionalToken(SyntaxKind.QuestionToken);
node.type = parseParameterType();
node.initializer = inGeneratorParameterContext() ? doOutsideOfYieldContext(parseParameterInitializer) : parseParameterInitializer();
node.initializer = parseBindingElementInitializer(/*inParameter*/ true);
// Do not check for initializers in an ambient context for parameters. This is not
// a grammar error because the grammar allows arbitrary call signatures in
@ -2010,19 +2013,25 @@ namespace ts {
// ambient contexts.
return finishNode(node);
}
function parseBindingElementInitializer(inParameter: boolean) {
return inParameter ? parseParameterInitializer() : parseNonParameterInitializer();
}
function parseParameterInitializer() {
return parseInitializer(/*inParameter*/ true);
}
function fillSignature(
returnToken: SyntaxKind,
yieldAndGeneratorParameterContext: boolean,
requireCompleteParameterList: boolean,
signature: SignatureDeclaration): void {
returnToken: SyntaxKind,
yieldContext: boolean,
awaitContext: boolean,
requireCompleteParameterList: boolean,
signature: SignatureDeclaration): void {
let returnTokenRequired = returnToken === SyntaxKind.EqualsGreaterThanToken;
signature.typeParameters = parseTypeParameters();
signature.parameters = parseParameterList(yieldAndGeneratorParameterContext, requireCompleteParameterList);
signature.parameters = parseParameterList(yieldContext, awaitContext, requireCompleteParameterList);
if (returnTokenRequired) {
parseExpected(returnToken);
@ -2033,37 +2042,32 @@ namespace ts {
}
}
// Note: after careful analysis of the grammar, it does not appear to be possible to
// have 'Yield' And 'GeneratorParameter' not in sync. i.e. any production calling
// this FormalParameters production either always sets both to true, or always sets
// both to false. As such we only have a single parameter to represent both.
function parseParameterList(yieldAndGeneratorParameterContext: boolean, requireCompleteParameterList: boolean) {
// FormalParameters[Yield,GeneratorParameter] :
// ...
function parseParameterList(yieldContext: boolean, awaitContext: boolean, requireCompleteParameterList: boolean) {
// FormalParameters [Yield,Await]: (modified)
// [empty]
// FormalParameterList[?Yield,Await]
//
// FormalParameter[Yield,GeneratorParameter] :
// BindingElement[?Yield, ?GeneratorParameter]
// FormalParameter[Yield,Await]: (modified)
// BindingElement[?Yield,Await]
//
// BindingElement[Yield, GeneratorParameter ] : See 13.2.3
// SingleNameBinding[?Yield, ?GeneratorParameter]
// [+GeneratorParameter]BindingPattern[?Yield, GeneratorParameter]Initializer[In]opt
// [~GeneratorParameter]BindingPattern[?Yield]Initializer[In, ?Yield]opt
// BindingElement [Yield,Await]: (modified)
// SingleNameBinding[?Yield,?Await]
// BindingPattern[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
//
// SingleNameBinding[Yield, GeneratorParameter] : See 13.2.3
// [+GeneratorParameter]BindingIdentifier[Yield]Initializer[In]opt
// [~GeneratorParameter]BindingIdentifier[?Yield]Initializer[In, ?Yield]opt
// SingleNameBinding [Yield,Await]:
// BindingIdentifier[?Yield,?Await]Initializer [In, ?Yield,?Await] opt
if (parseExpected(SyntaxKind.OpenParenToken)) {
let savedYieldContext = inYieldContext();
let savedGeneratorParameterContext = inGeneratorParameterContext();
setYieldContext(yieldAndGeneratorParameterContext);
setGeneratorParameterContext(yieldAndGeneratorParameterContext);
let savedAwaitContext = inAwaitContext();
setYieldContext(yieldContext);
setAwaitContext(awaitContext);
let result = parseDelimitedList(ParsingContext.Parameters, parseParameter);
setYieldContext(savedYieldContext);
setGeneratorParameterContext(savedGeneratorParameterContext);
setAwaitContext(savedAwaitContext);
if (!parseExpected(SyntaxKind.CloseParenToken) && requireCompleteParameterList) {
// Caller insisted that we had to end with a ) We didn't. So just return
// undefined here.
@ -2078,7 +2082,7 @@ namespace ts {
// then just return an empty set of parameters.
return requireCompleteParameterList ? undefined : createMissingList<ParameterDeclaration>();
}
function parseTypeMemberSemicolon() {
// We allow type members to be separated by commas or (possibly ASI) semicolons.
// First check if it was a comma. If so, we're done with the member.
@ -2095,7 +2099,7 @@ namespace ts {
if (kind === SyntaxKind.ConstructSignature) {
parseExpected(SyntaxKind.NewKeyword);
}
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ false, /*requireCompleteParameterList*/ false, node);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
parseTypeMemberSemicolon();
return finishNode(node);
}
@ -2184,8 +2188,8 @@ namespace ts {
method.questionToken = questionToken;
// Method signatues don't exist in expression contexts. So they have neither
// [Yield] nor [GeneratorParameter]
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ false, /*requireCompleteParameterList*/ false, method);
// [Yield] nor [Await]
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, method);
parseTypeMemberSemicolon();
return finishNode(method);
}
@ -2324,7 +2328,7 @@ namespace ts {
if (kind === SyntaxKind.ConstructorType) {
parseExpected(SyntaxKind.NewKeyword);
}
fillSignature(SyntaxKind.EqualsGreaterThanToken, /*yieldAndGeneratorParameterContext*/ false, /*requireCompleteParameterList*/ false, node);
fillSignature(SyntaxKind.EqualsGreaterThanToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
return finishNode(node);
}
@ -2453,19 +2457,8 @@ namespace ts {
function parseType(): TypeNode {
// The rules about 'yield' only apply to actual code/expression contexts. They don't
// apply to 'type' contexts. So we disable these parameters here before moving on.
let savedYieldContext = inYieldContext();
let savedGeneratorParameterContext = inGeneratorParameterContext();
setYieldContext(false);
setGeneratorParameterContext(false);
let result = parseTypeWorker();
setYieldContext(savedYieldContext);
setGeneratorParameterContext(savedGeneratorParameterContext);
return result;
// apply to 'type' contexts. So we disable these parameters here before moving on.
return doOutsideOfContext(ParserContextFlags.TypeExcludesFlags, parseTypeWorker);
}
function parseTypeWorker(): TypeNode {
@ -2525,10 +2518,11 @@ namespace ts {
case SyntaxKind.PlusPlusToken:
case SyntaxKind.MinusMinusToken:
case SyntaxKind.LessThanToken:
case SyntaxKind.AwaitKeyword:
case SyntaxKind.YieldKeyword:
// Yield always starts an expression. Either it is an identifier (in which case
// Yield/await always starts an expression. Either it is an identifier (in which case
// it is definitely an expression). Or it's a keyword (either because we're in
// a generator, or in strict mode (or both)) and it started a yield expression.
// a generator or async function, or in strict mode (or both)) and it started a yield or await expression.
return true;
default:
// Error tolerance. If we see the start of some binary operator, we consider
@ -2551,6 +2545,10 @@ namespace ts {
token !== SyntaxKind.AtToken &&
isStartOfExpression();
}
function allowInAndParseExpression(): Expression {
return allowInAnd(parseExpression);
}
function parseExpression(): Expression {
// Expression[in]:
@ -2725,19 +2723,18 @@ namespace ts {
node.parameters.end = parameter.end;
node.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, false, Diagnostics._0_expected, "=>");
node.body = parseArrowFunctionExpressionBody();
node.body = parseArrowFunctionExpressionBody(/*isAsync*/ false);
return finishNode(node);
}
function tryParseParenthesizedArrowFunctionExpression(): Expression {
let triState = isParenthesizedArrowFunctionExpression();
if (triState === Tristate.False) {
// It's definitely not a parenthesized arrow function expression.
return undefined;
}
// If we definitely have an arrow function, then we can just parse one, not requiring a
// following => or { token. Otherwise, we *might* have an arrow function. Try to parse
// it out, but don't allow any ambiguity, and return 'undefined' if this could be an
@ -2750,13 +2747,15 @@ namespace ts {
// Didn't appear to actually be a parenthesized arrow function. Just bail out.
return undefined;
}
let isAsync = !!(arrowFunction.flags & NodeFlags.Async);
// If we have an arrow, then try to parse the body. Even if not, try to parse if we
// have an opening brace, just in case we're in an error state.
var lastToken = token;
arrowFunction.equalsGreaterThanToken = parseExpectedToken(SyntaxKind.EqualsGreaterThanToken, /*reportAtCurrentPosition*/false, Diagnostics._0_expected, "=>");
arrowFunction.body = (lastToken === SyntaxKind.EqualsGreaterThanToken || lastToken === SyntaxKind.OpenBraceToken)
? parseArrowFunctionExpressionBody()
? parseArrowFunctionExpressionBody(isAsync)
: parseIdentifier();
return finishNode(arrowFunction);
@ -2767,7 +2766,7 @@ namespace ts {
// Unknown -> There *might* be a parenthesized arrow function here.
// Speculatively look ahead to be sure, and rollback if not.
function isParenthesizedArrowFunctionExpression(): Tristate {
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken) {
if (token === SyntaxKind.OpenParenToken || token === SyntaxKind.LessThanToken || token === SyntaxKind.AsyncKeyword) {
return lookAhead(isParenthesizedArrowFunctionExpressionWorker);
}
@ -2782,6 +2781,16 @@ namespace ts {
}
function isParenthesizedArrowFunctionExpressionWorker() {
if (token === SyntaxKind.AsyncKeyword) {
nextToken();
if (scanner.hasPrecedingLineBreak()) {
return Tristate.False;
}
if (token !== SyntaxKind.OpenParenToken && token !== SyntaxKind.LessThanToken) {
return Tristate.False;
}
}
let first = token;
let second = nextToken();
@ -2884,6 +2893,9 @@ namespace ts {
function parseParenthesizedArrowFunctionExpressionHead(allowAmbiguity: boolean): ArrowFunction {
let node = <ArrowFunction>createNode(SyntaxKind.ArrowFunction);
setModifiers(node, parseModifiersForArrowFunction());
let isAsync = !!(node.flags & NodeFlags.Async);
// Arrow functions are never generators.
//
// If we're speculatively parsing a signature for a parenthesized arrow function, then
@ -2891,7 +2903,7 @@ namespace ts {
// a => (b => c)
// And think that "(b =>" was actually a parenthesized arrow function with a missing
// close paren.
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ false, /*requireCompleteParameterList*/ !allowAmbiguity, node);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ !allowAmbiguity, node);
// If we couldn't get parameters, we definitely could not parse out an arrow function.
if (!node.parameters) {
@ -2914,9 +2926,9 @@ namespace ts {
return node;
}
function parseArrowFunctionExpressionBody(): Block | Expression {
function parseArrowFunctionExpressionBody(isAsync: boolean): Block | Expression {
if (token === SyntaxKind.OpenBraceToken) {
return parseFunctionBlock(/*allowYield*/ false, /*ignoreMissingOpenBrace*/ false);
return parseFunctionBlock(/*allowYield*/ false, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
}
if (token !== SyntaxKind.SemicolonToken &&
@ -2938,10 +2950,12 @@ namespace ts {
// up preemptively closing the containing construct.
//
// Note: even when 'ignoreMissingOpenBrace' is passed as true, parseBody will still error.
return parseFunctionBlock(/*allowYield*/ false, /*ignoreMissingOpenBrace*/ true);
return parseFunctionBlock(/*allowYield*/ false, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ true);
}
return parseAssignmentExpressionOrHigher();
return isAsync
? doInAwaitContext(parseAssignmentExpressionOrHigher)
: doOutsideOfAwaitContext(parseAssignmentExpressionOrHigher);
}
function parseConditionalExpressionRest(leftOperand: Expression): Expression {
@ -3105,8 +3119,32 @@ namespace ts {
node.expression = parseUnaryExpressionOrHigher();
return finishNode(node);
}
function isAwaitExpression(): boolean {
if (token === SyntaxKind.AwaitKeyword) {
if (inAwaitContext()) {
return true;
}
// here we are using similar heuristics as 'isYieldExpression'
return lookAhead(nextTokenIsIdentifierOnSameLine);
}
return false;
}
function parseAwaitExpression() {
var node = <AwaitExpression>createNode(SyntaxKind.AwaitExpression);
nextToken();
node.expression = parseUnaryExpressionOrHigher();
return finishNode(node);
}
function parseUnaryExpressionOrHigher(): UnaryExpression {
if (isAwaitExpression()) {
return parseAwaitExpression();
}
switch (token) {
case SyntaxKind.PlusToken:
case SyntaxKind.MinusToken:
@ -3574,6 +3612,15 @@ namespace ts {
return parseArrayLiteralExpression();
case SyntaxKind.OpenBraceToken:
return parseObjectLiteralExpression();
case SyntaxKind.AsyncKeyword:
// Async arrow functions are parsed earlier in parseAssignmentExpressionOrHigher.
// If we encounter `async [no LineTerminator here] function` then this is an async
// function; otherwise, its an identifier.
if (!lookAhead(nextTokenIsFunctionKeywordOnSameLine)) {
break;
}
return parseFunctionExpression();
case SyntaxKind.ClassKeyword:
return parseClassExpression();
case SyntaxKind.FunctionKeyword:
@ -3689,23 +3736,36 @@ namespace ts {
}
function parseFunctionExpression(): FunctionExpression {
// GeneratorExpression :
// function * BindingIdentifier[Yield]opt (FormalParameters[Yield, GeneratorParameter]) { GeneratorBody[Yield] }
// GeneratorExpression:
// function* BindingIdentifier [Yield][opt](FormalParameters[Yield]){ GeneratorBody }
//
// FunctionExpression:
// function BindingIdentifieropt(FormalParameters) { FunctionBody }
// function BindingIdentifier[opt](FormalParameters){ FunctionBody }
let saveDecoratorContext = inDecoratorContext();
if (saveDecoratorContext) {
setDecoratorContext(false);
}
let node = <FunctionExpression>createNode(SyntaxKind.FunctionExpression);
setModifiers(node, parseModifiers());
parseExpected(SyntaxKind.FunctionKeyword);
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
node.name = node.asteriskToken ? doInYieldContext(parseOptionalIdentifier) : parseOptionalIdentifier();
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ !!node.asteriskToken, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlock(/*allowYield*/ !!node.asteriskToken, /* ignoreMissingOpenBrace */ false);
let isGenerator = !!node.asteriskToken;
let isAsync = !!(node.flags & NodeFlags.Async);
node.name =
isGenerator && isAsync ? doInYieldAndAwaitContext(parseOptionalIdentifier) :
isGenerator ? doInYieldContext(parseOptionalIdentifier) :
isAsync ? doInAwaitContext(parseOptionalIdentifier) :
parseOptionalIdentifier();
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlock(/*allowYield*/ isGenerator, /*allowAwait*/ isAsync, /*ignoreMissingOpenBrace*/ false);
if (saveDecoratorContext) {
setDecoratorContext(true);
}
return finishNode(node);
}
@ -3738,9 +3798,12 @@ namespace ts {
return finishNode(node);
}
function parseFunctionBlock(allowYield: boolean, ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block {
function parseFunctionBlock(allowYield: boolean, allowAwait: boolean, ignoreMissingOpenBrace: boolean, diagnosticMessage?: DiagnosticMessage): Block {
let savedYieldContext = inYieldContext();
setYieldContext(allowYield);
let savedAwaitContext = inAwaitContext();
setAwaitContext(allowAwait);
// We may be in a [Decorator] context when parsing a function expression or
// arrow function. The body of the function is not in [Decorator] context.
@ -3756,6 +3819,7 @@ namespace ts {
}
setYieldContext(savedYieldContext);
setAwaitContext(savedAwaitContext);
return block;
}
@ -4003,6 +4067,11 @@ namespace ts {
nextToken();
return isIdentifierOrKeyword() && !scanner.hasPrecedingLineBreak();
}
function nextTokenIsFunctionKeywordOnSameLine() {
nextToken();
return token === SyntaxKind.FunctionKeyword && !scanner.hasPrecedingLineBreak();
}
function nextTokenIsIdentifierOrKeywordOrNumberOnSameLine() {
nextToken();
@ -4047,6 +4116,7 @@ namespace ts {
case SyntaxKind.ModuleKeyword:
case SyntaxKind.NamespaceKeyword:
return nextTokenIsIdentifierOrStringLiteralOnSameLine();
case SyntaxKind.AsyncKeyword:
case SyntaxKind.DeclareKeyword:
nextToken();
// ASI takes effect for this modifier.
@ -4066,6 +4136,7 @@ namespace ts {
return true;
}
continue;
case SyntaxKind.PublicKeyword:
case SyntaxKind.PrivateKeyword:
case SyntaxKind.ProtectedKeyword:
@ -4115,6 +4186,7 @@ namespace ts {
case SyntaxKind.ImportKeyword:
return isStartOfDeclaration();
case SyntaxKind.AsyncKeyword:
case SyntaxKind.DeclareKeyword:
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.ModuleKeyword:
@ -4193,7 +4265,7 @@ namespace ts {
return parseDebuggerStatement();
case SyntaxKind.AtToken:
return parseDeclaration();
case SyntaxKind.AsyncKeyword:
case SyntaxKind.InterfaceKeyword:
case SyntaxKind.TypeKeyword:
case SyntaxKind.ModuleKeyword:
@ -4262,13 +4334,13 @@ namespace ts {
return !scanner.hasPrecedingLineBreak() && (isIdentifier() || token === SyntaxKind.StringLiteral);
}
function parseFunctionBlockOrSemicolon(isGenerator: boolean, diagnosticMessage?: DiagnosticMessage): Block {
function parseFunctionBlockOrSemicolon(isGenerator: boolean, isAsync: boolean, diagnosticMessage?: DiagnosticMessage): Block {
if (token !== SyntaxKind.OpenBraceToken && canParseSemicolon()) {
parseSemicolon();
return;
}
return parseFunctionBlock(isGenerator, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
return parseFunctionBlock(isGenerator, isAsync, /*ignoreMissingOpenBrace*/ false, diagnosticMessage);
}
// DECLARATIONS
@ -4280,7 +4352,7 @@ namespace ts {
let node = <BindingElement>createNode(SyntaxKind.BindingElement);
node.dotDotDotToken = parseOptionalToken(SyntaxKind.DotDotDotToken);
node.name = parseIdentifierOrPattern();
node.initializer = parseInitializer(/*inParameter*/ false);
node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
return finishNode(node);
}
@ -4297,7 +4369,7 @@ namespace ts {
node.propertyName = <Identifier>propertyName;
node.name = parseIdentifierOrPattern();
}
node.initializer = parseInitializer(/*inParameter*/ false);
node.initializer = parseBindingElementInitializer(/*inParameter*/ false);
return finishNode(node);
}
@ -4403,8 +4475,10 @@ namespace ts {
parseExpected(SyntaxKind.FunctionKeyword);
node.asteriskToken = parseOptionalToken(SyntaxKind.AsteriskToken);
node.name = node.flags & NodeFlags.Default ? parseOptionalIdentifier() : parseIdentifier();
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ !!node.asteriskToken, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(!!node.asteriskToken, Diagnostics.or_expected);
let isGenerator = !!node.asteriskToken;
let isAsync = !!(node.flags & NodeFlags.Async);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, Diagnostics.or_expected);
return finishNode(node);
}
@ -4413,8 +4487,8 @@ namespace ts {
node.decorators = decorators;
setModifiers(node, modifiers);
parseExpected(SyntaxKind.ConstructorKeyword);
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ false, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, Diagnostics.or_expected);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false, Diagnostics.or_expected);
return finishNode(node);
}
@ -4425,8 +4499,10 @@ namespace ts {
method.asteriskToken = asteriskToken;
method.name = name;
method.questionToken = questionToken;
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ !!asteriskToken, /*requireCompleteParameterList*/ false, method);
method.body = parseFunctionBlockOrSemicolon(!!asteriskToken, diagnosticMessage);
let isGenerator = !!asteriskToken;
let isAsync = !!(method.flags & NodeFlags.Async);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ isGenerator, /*awaitContext*/ isAsync, /*requireCompleteParameterList*/ false, method);
method.body = parseFunctionBlockOrSemicolon(isGenerator, isAsync, diagnosticMessage);
return finishNode(method);
}
@ -4479,8 +4555,8 @@ namespace ts {
node.decorators = decorators;
setModifiers(node, modifiers);
node.name = parsePropertyName();
fillSignature(SyntaxKind.ColonToken, /*yieldAndGeneratorParameterContext*/ false, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false);
fillSignature(SyntaxKind.ColonToken, /*yieldContext*/ false, /*awaitContext*/ false, /*requireCompleteParameterList*/ false, node);
node.body = parseFunctionBlockOrSemicolon(/*isGenerator*/ false, /*isAsync*/ false);
return finishNode(node);
}
@ -4602,6 +4678,7 @@ namespace ts {
modifiers = <ModifiersArray>[];
modifiers.pos = modifierStart;
}
flags |= modifierToFlag(modifierKind);
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
}
@ -4612,6 +4689,24 @@ namespace ts {
return modifiers;
}
function parseModifiersForArrowFunction(): ModifiersArray {
let flags = 0;
let modifiers: ModifiersArray;
if (token === SyntaxKind.AsyncKeyword) {
let modifierStart = scanner.getStartPos();
let modifierKind = token;
nextToken();
modifiers = <ModifiersArray>[];
modifiers.pos = modifierStart;
flags |= modifierToFlag(modifierKind);
modifiers.push(finishNode(createNode(modifierKind, modifierStart)));
modifiers.flags = flags;
modifiers.end = scanner.getStartPos();
}
return modifiers;
}
function parseClassElement(): ClassElement {
if (token === SyntaxKind.SemicolonToken) {
let result = <SemicolonClassElement>createNode(SyntaxKind.SemicolonClassElement);
@ -4668,7 +4763,7 @@ namespace ts {
function parseClassDeclaration(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray): ClassDeclaration {
return <ClassDeclaration>parseClassDeclarationOrExpression(fullStart, decorators, modifiers, SyntaxKind.ClassDeclaration);
}
function parseClassDeclarationOrExpression(fullStart: number, decorators: NodeArray<Decorator>, modifiers: ModifiersArray, kind: SyntaxKind): ClassLikeDeclaration {
var node = <ClassLikeDeclaration>createNode(kind, fullStart);
node.decorators = decorators;
@ -4679,13 +4774,9 @@ namespace ts {
node.heritageClauses = parseHeritageClauses(/*isClassHeritageClause*/ true);
if (parseExpected(SyntaxKind.OpenBraceToken)) {
// ClassTail[Yield,GeneratorParameter] : See 14.5
// [~GeneratorParameter]ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
// [+GeneratorParameter] ClassHeritageopt { ClassBodyopt }
node.members = inGeneratorParameterContext()
? doOutsideOfYieldContext(parseClassMembers)
: parseClassMembers();
// ClassTail[Yield,Await] : (Modified) See 14.5
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
node.members = parseClassMembers();
parseExpected(SyntaxKind.CloseBraceToken);
}
else {
@ -4696,14 +4787,11 @@ namespace ts {
}
function parseHeritageClauses(isClassHeritageClause: boolean): NodeArray<HeritageClause> {
// ClassTail[Yield,GeneratorParameter] : See 14.5
// [~GeneratorParameter]ClassHeritage[?Yield]opt { ClassBody[?Yield]opt }
// [+GeneratorParameter] ClassHeritageopt { ClassBodyopt }
// ClassTail[Yield,Await] : (Modified) See 14.5
// ClassHeritage[?Yield,?Await]opt { ClassBody[?Yield,?Await]opt }
if (isHeritageClause()) {
return isClassHeritageClause && inGeneratorParameterContext()
? doOutsideOfYieldContext(parseHeritageClausesWorker)
: parseHeritageClausesWorker();
return parseList(ParsingContext.HeritageClauses, parseHeritageClause);
}
return undefined;

View File

@ -674,6 +674,11 @@ namespace ts {
!options.experimentalDecorators) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalDecorators_must_also_be_specified_when_option_emitDecoratorMetadata_is_specified));
}
if (options.experimentalAsyncFunctions &&
options.target !== ScriptTarget.ES6) {
diagnostics.add(createCompilerDiagnostic(Diagnostics.Option_experimentalAsyncFunctions_cannot_be_specified_when_targeting_ES5_or_lower));
}
}
}
}

View File

@ -106,6 +106,8 @@ namespace ts {
"while": SyntaxKind.WhileKeyword,
"with": SyntaxKind.WithKeyword,
"yield": SyntaxKind.YieldKeyword,
"async": SyntaxKind.AsyncKeyword,
"await": SyntaxKind.AwaitKeyword,
"of": SyntaxKind.OfKeyword,
"{": SyntaxKind.OpenBraceToken,
"}": SyntaxKind.CloseBraceToken,

View File

@ -142,6 +142,8 @@ namespace ts {
// Contextual keywords
AsKeyword,
AnyKeyword,
AsyncKeyword,
AwaitKeyword,
BooleanKeyword,
ConstructorKeyword,
DeclareKeyword,
@ -208,6 +210,7 @@ namespace ts {
DeleteExpression,
TypeOfExpression,
VoidExpression,
AwaitExpression,
PrefixUnaryExpression,
PostfixUnaryExpression,
BinaryExpression,
@ -365,8 +368,9 @@ namespace ts {
OctalLiteral = 0x00004000, // Octal numeric literal
Namespace = 0x00008000, // Namespace declaration
ExportContext = 0x00010000, // Export context (initialized by binding)
Async = 0x00020000, // Property/Method/Function
Modifier = Export | Ambient | Public | Private | Protected | Static | Default,
Modifier = Export | Ambient | Public | Private | Protected | Static | Default | Async,
AccessibilityModifier = Public | Private | Protected,
BlockScoped = Let | Const
}
@ -376,37 +380,40 @@ namespace ts {
None = 0,
// If this node was parsed in a context where 'in-expressions' are not allowed.
DisallowIn = 1 << 1,
DisallowIn = 1 << 0,
// If this node was parsed in the 'yield' context created when parsing a generator.
Yield = 1 << 2,
// If this node was parsed in the parameters of a generator.
GeneratorParameter = 1 << 3,
Yield = 1 << 1,
// If this node was parsed as part of a decorator
Decorator = 1 << 4,
Decorator = 1 << 2,
// If this node was parsed in the 'await' context created when parsing an async function.
Await = 1 << 3,
// If the parser encountered an error when parsing the code that created this node. Note
// the parser only sets this directly on the node it creates right after encountering the
// error.
ThisNodeHasError = 1 << 5,
ThisNodeHasError = 1 << 4,
// This node was parsed in a JavaScript file and can be processed differently. For example
// its type can be specified usign a JSDoc comment.
JavaScriptFile = 1 << 6,
JavaScriptFile = 1 << 5,
// Context flags set directly by the parser.
ParserGeneratedFlags = DisallowIn | Yield | GeneratorParameter | Decorator | ThisNodeHasError,
ParserGeneratedFlags = DisallowIn | Yield | Decorator | ThisNodeHasError | Await,
// Exclude these flags when parsing a Type
TypeExcludesFlags = Yield | Await,
// Context flags computed by aggregating child flags upwards.
// Used during incremental parsing to determine if this node or any of its children had an
// error. Computed only once and then cached.
ThisNodeOrAnySubNodesHasError = 1 << 7,
ThisNodeOrAnySubNodesHasError = 1 << 6,
// Used to know if we've computed data from children and cached it in this node.
HasAggregatedChildData = 1 << 8
HasAggregatedChildData = 1 << 7
}
export const enum JsxFlags {
@ -726,6 +733,10 @@ namespace ts {
expression: UnaryExpression;
}
export interface AwaitExpression extends UnaryExpression {
expression: UnaryExpression;
}
export interface YieldExpression extends Expression {
asteriskToken?: Node;
expression?: Expression;
@ -1658,21 +1669,26 @@ namespace ts {
LexicalThis = 0x00000002, // Lexical 'this' reference
CaptureThis = 0x00000004, // Lexical 'this' used in body
EmitExtends = 0x00000008, // Emit __extends
SuperInstance = 0x00000010, // Instance 'super' reference
SuperStatic = 0x00000020, // Static 'super' reference
ContextChecked = 0x00000040, // Contextual types have been assigned
EmitDecorate = 0x00000010, // Emit __decorate
EmitParam = 0x00000020, // Emit __param helper for decorators
EmitAwaiter = 0x00000040, // Emit __awaiter
EmitGenerator = 0x00000080, // Emit __generator
SuperInstance = 0x00000100, // Instance 'super' reference
SuperStatic = 0x00000200, // Static 'super' reference
ContextChecked = 0x00000400, // Contextual types have been assigned
LexicalArguments = 0x00000800,
CaptureArguments = 0x00001000, // Lexical 'arguments' used in body (for async functions)
// Values for enum members have been computed, and any errors have been reported for them.
EnumValuesComputed = 0x00000080,
BlockScopedBindingInLoop = 0x00000100,
EmitDecorate = 0x00000200, // Emit __decorate
EmitParam = 0x00000400, // Emit __param helper for decorators
LexicalModuleMergesWithClass = 0x00000800, // Instantiated lexical module declaration is merged with a previous class declaration.
EnumValuesComputed = 0x00002000,
BlockScopedBindingInLoop = 0x00004000,
LexicalModuleMergesWithClass= 0x00008000, // Instantiated lexical module declaration is merged with a previous class declaration.
}
/* @internal */
export interface NodeLinks {
resolvedType?: Type; // Cached type of type node
resolvedAwaitedType?: Type; // Cached awaited type of type node
resolvedSignature?: Signature; // Cached signature of signature node or call expression
resolvedSymbol?: Symbol; // Cached name resolution result
flags?: NodeCheckFlags; // Set of flags specific to Node
@ -1944,6 +1960,7 @@ namespace ts {
watch?: boolean;
isolatedModules?: boolean;
experimentalDecorators?: boolean;
experimentalAsyncFunctions?: boolean;
emitDecoratorMetadata?: boolean;
/* @internal */ stripInternal?: boolean;

View File

@ -746,6 +746,22 @@ namespace ts {
}
}
}
export function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression {
if (node) {
switch (node.kind) {
case SyntaxKind.TypeReference:
return (<TypeReferenceNode>node).typeName;
case SyntaxKind.ExpressionWithTypeArguments:
return (<ExpressionWithTypeArguments>node).expression
case SyntaxKind.Identifier:
case SyntaxKind.QualifiedName:
return (<EntityName><Node>node);
}
}
return undefined;
}
export function getInvokedExpression(node: CallLikeExpression): Expression {
if (node.kind === SyntaxKind.TaggedTemplateExpression) {
@ -1321,6 +1337,10 @@ namespace ts {
return SyntaxKind.FirstTriviaToken <= token && token <= SyntaxKind.LastTriviaToken;
}
export function isAsyncFunctionLike(node: Node): boolean {
return isFunctionLike(node) && (node.flags & NodeFlags.Async) !== 0 && !isAccessor(node);
}
/**
* A declaration has a dynamic name if both of the following are true:
* 1. The declaration has a computed property name
@ -1379,6 +1399,7 @@ namespace ts {
case SyntaxKind.DeclareKeyword:
case SyntaxKind.ConstKeyword:
case SyntaxKind.DefaultKeyword:
case SyntaxKind.AsyncKeyword:
return true;
}
return false;
@ -1883,6 +1904,7 @@ namespace ts {
case SyntaxKind.DeclareKeyword: return NodeFlags.Ambient;
case SyntaxKind.ConstKeyword: return NodeFlags.Const;
case SyntaxKind.DefaultKeyword: return NodeFlags.Default;
case SyntaxKind.AsyncKeyword: return NodeFlags.Async;
}
return 0;
}
@ -1947,7 +1969,7 @@ namespace ts {
return false;
}
}
export function isRightSideOfQualifiedNameOrPropertyAccess(node: Node) {
return (node.parent.kind === SyntaxKind.QualifiedName && (<QualifiedName>node.parent).right === node) ||
(node.parent.kind === SyntaxKind.PropertyAccessExpression && (<PropertyAccessExpression>node.parent).name === node);

View File

@ -1055,6 +1055,10 @@ module Harness {
case 'emitdecoratormetadata':
options.emitDecoratorMetadata = setting.value === 'true';
break;
case 'experimentalasyncfunctions':
options.experimentalAsyncFunctions = setting.value === 'true';
break;
case 'noemithelpers':
options.noEmitHelpers = setting.value === 'true';

View File

@ -49,6 +49,7 @@ if (testConfigFile !== '') {
if (!option) {
continue;
}
switch (option) {
case 'compiler':
runners.push(new CompilerBaselineRunner(CompilerTestType.Conformance));

13
src/lib/core.d.ts vendored
View File

@ -1169,3 +1169,16 @@ declare type ClassDecorator = <TFunction extends Function>(target: TFunction) =>
declare type PropertyDecorator = (target: Object, propertyKey: string | symbol) => void;
declare type MethodDecorator = <T>(target: Object, propertyKey: string | symbol, descriptor: TypedPropertyDescriptor<T>) => TypedPropertyDescriptor<T> | void;
declare type ParameterDecorator = (target: Object, propertyKey: string | symbol, parameterIndex: number) => void;
declare type PromiseConstructorLike = new <T>(executor: (resolve: (value?: T | PromiseLike<T>) => void, reject: (reason?: any) => void) => void) => PromiseLike<T>;
interface PromiseLike<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
}

12
src/lib/es6.d.ts vendored
View File

@ -3573,17 +3573,6 @@ declare module Reflect {
function setPrototypeOf(target: any, proto: any): boolean;
}
interface PromiseLike<T> {
/**
* Attaches callbacks for the resolution and/or rejection of the Promise.
* @param onfulfilled The callback to execute when the Promise is resolved.
* @param onrejected The callback to execute when the Promise is rejected.
* @returns A Promise for the completion of which ever callback is executed.
*/
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => TResult | PromiseLike<TResult>): PromiseLike<TResult>;
then<TResult>(onfulfilled?: (value: T) => TResult | PromiseLike<TResult>, onrejected?: (reason: any) => void): PromiseLike<TResult>;
}
/**
* Represents the completion of an asynchronous operation
*/
@ -3603,6 +3592,7 @@ interface Promise<T> {
* @returns A Promise for the completion of the callback.
*/
catch(onrejected?: (reason: any) => T | PromiseLike<T>): Promise<T>;
catch(onrejected?: (reason: any) => void): Promise<T>;
[Symbol.toStringTag]: string;
}

View File

@ -75,26 +75,26 @@ function delint(sourceFile) {
delintNode(sourceFile);
function delintNode(node) {
switch (node.kind) {
case 191 /* ForStatement */:
case 192 /* ForInStatement */:
case 190 /* WhileStatement */:
case 189 /* DoStatement */:
if (node.statement.kind !== 184 /* Block */) {
case 194 /* ForStatement */:
case 195 /* ForInStatement */:
case 193 /* WhileStatement */:
case 192 /* DoStatement */:
if (node.statement.kind !== 187 /* Block */) {
report(node, "A looping statement's contents should be wrapped in a block body.");
}
break;
case 188 /* IfStatement */:
case 191 /* IfStatement */:
var ifStatement = node;
if (ifStatement.thenStatement.kind !== 184 /* Block */) {
if (ifStatement.thenStatement.kind !== 187 /* Block */) {
report(ifStatement.thenStatement, "An if statement's contents should be wrapped in a block body.");
}
if (ifStatement.elseStatement &&
ifStatement.elseStatement.kind !== 184 /* Block */ &&
ifStatement.elseStatement.kind !== 188 /* IfStatement */) {
ifStatement.elseStatement.kind !== 187 /* Block */ &&
ifStatement.elseStatement.kind !== 191 /* IfStatement */) {
report(ifStatement.elseStatement, "An else statement's contents should be wrapped in a block body.");
}
break;
case 173 /* BinaryExpression */:
case 176 /* BinaryExpression */:
var op = node.operatorToken.kind;
if (op === 29 /* EqualsEqualsToken */ || op == 30 /* ExclamationEqualsToken */) {
report(node, "Use '===' and '!=='.");

View File

@ -1,8 +1,20 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,10): error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,16): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,26): error TS1005: ',' expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,29): error TS1138: Parameter declaration expected.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,29): error TS2304: Cannot find name 'yield'.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts(1,34): error TS1005: ';' expected.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts (1 errors) ====
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration10_es6.ts (5 errors) ====
function * foo(a = yield => yield) {
~
!!! error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~
!!! error TS1005: ',' expected.
~~~~~
!!! error TS1138: Parameter declaration expected.
~~~~~
!!! error TS2304: Cannot find name 'yield'.
~
!!! error TS1005: ';' expected.
}

View File

@ -3,6 +3,6 @@ function * foo(a = yield => yield) {
}
//// [FunctionDeclaration10_es6.js]
function foo(a) {
if (a === void 0) { a = function (yield) { return yield; }; }
yield;
{
}

View File

@ -1,5 +1,5 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,9): error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,18): error TS2304: Cannot find name 'yield'.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,18): error TS2523: 'yield' expressions cannot be used in a parameter initializer.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts (2 errors) ====
@ -7,5 +7,5 @@ tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration6_es6.ts(1,1
~
!!! error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
~~~~~
!!! error TS2304: Cannot find name 'yield'.
!!! error TS2523: 'yield' expressions cannot be used in a parameter initializer.
}

View File

@ -1,6 +1,6 @@
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(1,9): error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(3,11): error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(3,20): error TS2304: Cannot find name 'yield'.
tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(3,20): error TS2523: 'yield' expressions cannot be used in a parameter initializer.
==== tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts (3 errors) ====
@ -12,6 +12,6 @@ tests/cases/conformance/es6/functionDeclarations/FunctionDeclaration7_es6.ts(3,2
~
!!! error TS1220: Generators are only available when targeting ECMAScript 6 or higher.
~~~~~
!!! error TS2304: Cannot find name 'yield'.
!!! error TS2523: 'yield' expressions cannot be used in a parameter initializer.
}
}

View File

@ -9,9 +9,9 @@ function doubleAndReturnAsArray(x: number, y: number, z: number): [number, numbe
let blah = arguments[Symbol.iterator];
>blah : Symbol(blah, Decl(argumentsObjectIterator02_ES6.ts, 2, 7))
>arguments : Symbol(arguments)
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
>Symbol : Symbol(Symbol, Decl(lib.d.ts, 1186, 52), Decl(lib.d.ts, 1292, 11))
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1236, 31))
>Symbol.iterator : Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1249, 31))
>Symbol : Symbol(Symbol, Decl(lib.d.ts, 1199, 52), Decl(lib.d.ts, 1305, 11))
>iterator : Symbol(SymbolConstructor.iterator, Decl(lib.d.ts, 1249, 31))
let result = [];
>result : Symbol(result, Decl(argumentsObjectIterator02_ES6.ts, 4, 7))

View File

@ -72,14 +72,14 @@ var temp2: [number[], string[]] = [[1, 2, 3], ["hello", "string"]];
interface myArray extends Array<Number> { }
>myArray : Symbol(myArray, Decl(arrayLiterals2ES6.ts, 40, 67))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1439, 1))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1452, 1))
>Number : Symbol(Number, Decl(lib.d.ts, 456, 40), Decl(lib.d.ts, 518, 11))
interface myArray2 extends Array<Number|String> { }
>myArray2 : Symbol(myArray2, Decl(arrayLiterals2ES6.ts, 42, 43))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1439, 1))
>Array : Symbol(Array, Decl(lib.d.ts, 1000, 23), Decl(lib.d.ts, 1171, 11), Decl(lib.d.ts, 1452, 1))
>Number : Symbol(Number, Decl(lib.d.ts, 456, 40), Decl(lib.d.ts, 518, 11))
>String : Symbol(String, Decl(lib.d.ts, 275, 1), Decl(lib.d.ts, 443, 11), Decl(lib.d.ts, 1543, 1))
>String : Symbol(String, Decl(lib.d.ts, 275, 1), Decl(lib.d.ts, 443, 11), Decl(lib.d.ts, 1556, 1))
var d0 = [1, true, ...temp, ]; // has type (string|number|boolean)[]
>d0 : Symbol(d0, Decl(arrayLiterals2ES6.ts, 44, 3))

View File

@ -0,0 +1,24 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(2,11): error TS2304: Cannot find name 'async'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(2,17): error TS1005: ',' expected.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(2,20): error TS1005: '=' expected.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(2,24): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts(4,11): error TS2304: Cannot find name 'await'.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction10_es6.ts (5 errors) ====
var foo = async foo(): Promise<void> => {
~~~~~
!!! error TS2304: Cannot find name 'async'.
~~~
!!! error TS1005: ',' expected.
~
!!! error TS1005: '=' expected.
~~~~~~~~~~~~~
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
// Legal to use 'await' in a type context.
var v: await;
~~~~~
!!! error TS2304: Cannot find name 'await'.
}

View File

@ -0,0 +1,13 @@
//// [asyncArrowFunction10_es6.ts]
var foo = async foo(): Promise<void> => {
// Legal to use 'await' in a type context.
var v: await;
}
//// [asyncArrowFunction10_es6.js]
var foo = async, foo = () => {
// Legal to use 'await' in a type context.
var v;
};

View File

@ -0,0 +1,8 @@
//// [asyncArrowFunction1_es6.ts]
var foo = async (): Promise<void> => {
};
//// [asyncArrowFunction1_es6.js]
var foo = () => __awaiter(this, void 0, Promise, function* () {
});

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction1_es6.ts ===
var foo = async (): Promise<void> => {
>foo : Symbol(foo, Decl(asyncArrowFunction1_es6.ts, 1, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
};

View File

@ -0,0 +1,8 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction1_es6.ts ===
var foo = async (): Promise<void> => {
>foo : () => Promise<void>
>async (): Promise<void> => {} : () => Promise<void>
>Promise : Promise<T>
};

View File

@ -0,0 +1,7 @@
//// [asyncArrowFunction2_es6.ts]
var f = (await) => {
}
//// [asyncArrowFunction2_es6.js]
var f = (await) => {
};

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction2_es6.ts ===
var f = (await) => {
>f : Symbol(f, Decl(asyncArrowFunction2_es6.ts, 0, 3))
>await : Symbol(await, Decl(asyncArrowFunction2_es6.ts, 0, 9))
}

View File

@ -0,0 +1,6 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction2_es6.ts ===
var f = (await) => {
>f : (await: any) => void
>(await) => {} : (await: any) => void
>await : any
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction3_es6.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction3_es6.ts (1 errors) ====
function f(await = await) {
~~~~~
!!! error TS2372: Parameter 'await' cannot be referenced in its initializer.
}

View File

@ -0,0 +1,7 @@
//// [asyncArrowFunction3_es6.ts]
function f(await = await) {
}
//// [asyncArrowFunction3_es6.js]
function f(await = await) {
}

View File

@ -0,0 +1,7 @@
//// [asyncArrowFunction4_es6.ts]
var await = () => {
}
//// [asyncArrowFunction4_es6.js]
var await = () => {
};

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction4_es6.ts ===
var await = () => {
>await : Symbol(await, Decl(asyncArrowFunction4_es6.ts, 0, 3))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction4_es6.ts ===
var await = () => {
>await : () => void
>() => {} : () => void
}

View File

@ -0,0 +1,24 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(2,11): error TS2304: Cannot find name 'async'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(2,18): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(2,24): error TS1005: ',' expected.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(2,26): error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(2,33): error TS1005: '=' expected.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts(2,40): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction5_es6.ts (6 errors) ====
var foo = async (await): Promise<void> => {
~~~~~
!!! error TS2304: Cannot find name 'async'.
~~~~~
!!! error TS2304: Cannot find name 'await'.
~
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
~
!!! error TS1005: '=' expected.
~~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,9 @@
//// [asyncArrowFunction5_es6.ts]
var foo = async (await): Promise<void> => {
}
//// [asyncArrowFunction5_es6.js]
var foo = async(await), Promise = ;
{
}

View File

@ -0,0 +1,12 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction6_es6.ts(2,22): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction6_es6.ts(2,27): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction6_es6.ts (2 errors) ====
var foo = async (a = await): Promise<void> => {
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,8 @@
//// [asyncArrowFunction6_es6.ts]
var foo = async (a = await): Promise<void> => {
}
//// [asyncArrowFunction6_es6.js]
var foo = (a = yield ) => __awaiter(this, void 0, Promise, function* () {
});

View File

@ -0,0 +1,15 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction7_es6.ts(4,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction7_es6.ts(4,29): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction7_es6.ts (2 errors) ====
var bar = async (): Promise<void> => {
// 'await' here is an identifier, and not an await expression.
var foo = async (a = await): Promise<void> => {
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~
!!! error TS1109: Expression expected.
}
}

View File

@ -0,0 +1,14 @@
//// [asyncArrowFunction7_es6.ts]
var bar = async (): Promise<void> => {
// 'await' here is an identifier, and not an await expression.
var foo = async (a = await): Promise<void> => {
}
}
//// [asyncArrowFunction7_es6.js]
var bar = () => __awaiter(this, void 0, Promise, function* () {
// 'await' here is an identifier, and not an await expression.
var foo = (a = yield ) => __awaiter(this, void 0, Promise, function* () {
});
});

View File

@ -0,0 +1,10 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction8_es6.ts(3,19): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction8_es6.ts (1 errors) ====
var foo = async (): Promise<void> => {
var v = { [await]: foo }
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,10 @@
//// [asyncArrowFunction8_es6.ts]
var foo = async (): Promise<void> => {
var v = { [await]: foo }
}
//// [asyncArrowFunction8_es6.js]
var foo = () => __awaiter(this, void 0, Promise, function* () {
var v = { [yield ]: foo };
});

View File

@ -0,0 +1,23 @@
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(1,11): error TS2304: Cannot find name 'async'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(1,18): error TS2304: Cannot find name 'a'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(1,37): error TS1005: ',' expected.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(1,39): error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(1,46): error TS1005: '=' expected.
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts(1,53): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunction9_es6.ts (6 errors) ====
var foo = async (a = await => await): Promise<void> => {
~~~~~
!!! error TS2304: Cannot find name 'async'.
~
!!! error TS2304: Cannot find name 'a'.
~
!!! error TS1005: ',' expected.
~~~~~~~
!!! error TS2403: Subsequent variable declarations must have the same type. Variable 'Promise' must be of type 'PromiseConstructor', but here has type 'void'.
~
!!! error TS1005: '=' expected.
~~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,8 @@
//// [asyncArrowFunction9_es6.ts]
var foo = async (a = await => await): Promise<void> => {
}
//// [asyncArrowFunction9_es6.js]
var foo = async(a = await => await), Promise = ;
{
}

View File

@ -0,0 +1,16 @@
//// [asyncArrowFunctionCapturesArguments_es6.ts]
class C {
method() {
function other() {}
var fn = async () => await other.apply(this, arguments);
}
}
//// [asyncArrowFunctionCapturesArguments_es6.js]
class C {
method() {
function other() { }
var fn = () => __awaiter(this, arguments, Promise, function* (_arguments) { return yield other.apply(this, _arguments); });
}
}

View File

@ -0,0 +1,20 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es6.ts ===
class C {
>C : Symbol(C, Decl(asyncArrowFunctionCapturesArguments_es6.ts, 0, 0))
method() {
>method : Symbol(method, Decl(asyncArrowFunctionCapturesArguments_es6.ts, 0, 9))
function other() {}
>other : Symbol(other, Decl(asyncArrowFunctionCapturesArguments_es6.ts, 1, 13))
var fn = async () => await other.apply(this, arguments);
>fn : Symbol(fn, Decl(asyncArrowFunctionCapturesArguments_es6.ts, 3, 9))
>other.apply : Symbol(Function.apply, Decl(lib.d.ts, 228, 20))
>other : Symbol(other, Decl(asyncArrowFunctionCapturesArguments_es6.ts, 1, 13))
>apply : Symbol(Function.apply, Decl(lib.d.ts, 228, 20))
>this : Symbol(C, Decl(asyncArrowFunctionCapturesArguments_es6.ts, 0, 0))
>arguments : Symbol(arguments)
}
}

View File

@ -0,0 +1,22 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es6.ts ===
class C {
>C : C
method() {
>method : () => void
function other() {}
>other : () => void
var fn = async () => await other.apply(this, arguments);
>fn : () => Promise<any>
>async () => await other.apply(this, arguments) : () => Promise<any>
>other.apply(this, arguments) : any
>other.apply : (thisArg: any, argArray?: any) => any
>other : () => void
>apply : (thisArg: any, argArray?: any) => any
>this : C
>arguments : IArguments
}
}

View File

@ -0,0 +1,14 @@
//// [asyncArrowFunctionCapturesThis_es6.ts]
class C {
method() {
var fn = async () => await this;
}
}
//// [asyncArrowFunctionCapturesThis_es6.js]
class C {
method() {
var fn = () => __awaiter(this, void 0, Promise, function* () { return yield this; });
}
}

View File

@ -0,0 +1,13 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunctionCapturesThis_es6.ts ===
class C {
>C : Symbol(C, Decl(asyncArrowFunctionCapturesThis_es6.ts, 0, 0))
method() {
>method : Symbol(method, Decl(asyncArrowFunctionCapturesThis_es6.ts, 0, 9))
var fn = async () => await this;
>fn : Symbol(fn, Decl(asyncArrowFunctionCapturesThis_es6.ts, 2, 9))
>this : Symbol(C, Decl(asyncArrowFunctionCapturesThis_es6.ts, 0, 0))
}
}

View File

@ -0,0 +1,14 @@
=== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunctionCapturesThis_es6.ts ===
class C {
>C : C
method() {
>method : () => void
var fn = async () => await this;
>fn : () => Promise<C>
>async () => await this : () => Promise<C>
>this : C
}
}

View File

@ -0,0 +1,45 @@
tests/cases/conformance/async/es6/asyncAwaitIsolatedModules_es6.ts(1,27): error TS2307: Cannot find module 'missing'.
==== tests/cases/conformance/async/es6/asyncAwaitIsolatedModules_es6.ts (1 errors) ====
import { MyPromise } from "missing";
~~~~~~~~~
!!! error TS2307: Cannot find module 'missing'.
declare var p: Promise<number>;
declare var mp: MyPromise<number>;
async function f0() { }
async function f1(): Promise<void> { }
async function f3(): MyPromise<void> { }
let f4 = async function() { }
let f5 = async function(): Promise<void> { }
let f6 = async function(): MyPromise<void> { }
let f7 = async () => { };
let f8 = async (): Promise<void> => { };
let f9 = async (): MyPromise<void> => { };
let f10 = async () => p;
let f11 = async () => mp;
let f12 = async (): Promise<number> => mp;
let f13 = async (): MyPromise<number> => p;
let o = {
async m1() { },
async m2(): Promise<void> { },
async m3(): MyPromise<void> { }
};
class C {
async m1() { }
async m2(): Promise<void> { }
async m3(): MyPromise<void> { }
static async m4() { }
static async m5(): Promise<void> { }
static async m6(): MyPromise<void> { }
}
module M {
export async function f1() { }
}

View File

@ -0,0 +1,118 @@
//// [asyncAwaitIsolatedModules_es6.ts]
import { MyPromise } from "missing";
declare var p: Promise<number>;
declare var mp: MyPromise<number>;
async function f0() { }
async function f1(): Promise<void> { }
async function f3(): MyPromise<void> { }
let f4 = async function() { }
let f5 = async function(): Promise<void> { }
let f6 = async function(): MyPromise<void> { }
let f7 = async () => { };
let f8 = async (): Promise<void> => { };
let f9 = async (): MyPromise<void> => { };
let f10 = async () => p;
let f11 = async () => mp;
let f12 = async (): Promise<number> => mp;
let f13 = async (): MyPromise<number> => p;
let o = {
async m1() { },
async m2(): Promise<void> { },
async m3(): MyPromise<void> { }
};
class C {
async m1() { }
async m2(): Promise<void> { }
async m3(): MyPromise<void> { }
static async m4() { }
static async m5(): Promise<void> { }
static async m6(): MyPromise<void> { }
}
module M {
export async function f1() { }
}
//// [asyncAwaitIsolatedModules_es6.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
return new Promise(function (resolve, reject) {
generator = generator.call(thisArg, _arguments);
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
function step(verb, value) {
var result = generator[verb](value);
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
}
step("next", void 0);
});
};
function f0() {
return __awaiter(this, void 0, Promise, function* () { });
}
function f1() {
return __awaiter(this, void 0, Promise, function* () { });
}
function f3() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
let f4 = function () {
return __awaiter(this, void 0, Promise, function* () { });
};
let f5 = function () {
return __awaiter(this, void 0, Promise, function* () { });
};
let f6 = function () {
return __awaiter(this, void 0, MyPromise, function* () { });
};
let f7 = () => __awaiter(this, void 0, Promise, function* () { });
let f8 = () => __awaiter(this, void 0, Promise, function* () { });
let f9 = () => __awaiter(this, void 0, MyPromise, function* () { });
let f10 = () => __awaiter(this, void 0, Promise, function* () { return p; });
let f11 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
let f12 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
let f13 = () => __awaiter(this, void 0, MyPromise, function* () { return p; });
let o = {
m1() {
return __awaiter(this, void 0, Promise, function* () { });
},
m2() {
return __awaiter(this, void 0, Promise, function* () { });
},
m3() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
};
class C {
m1() {
return __awaiter(this, void 0, Promise, function* () { });
}
m2() {
return __awaiter(this, void 0, Promise, function* () { });
}
m3() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
static m4() {
return __awaiter(this, void 0, Promise, function* () { });
}
static m5() {
return __awaiter(this, void 0, Promise, function* () { });
}
static m6() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
}
var M;
(function (M) {
function f1() {
return __awaiter(this, void 0, Promise, function* () { });
}
M.f1 = f1;
})(M || (M = {}));

View File

@ -0,0 +1,118 @@
//// [asyncAwait_es6.ts]
type MyPromise<T> = Promise<T>;
declare var MyPromise: typeof Promise;
declare var p: Promise<number>;
declare var mp: MyPromise<number>;
async function f0() { }
async function f1(): Promise<void> { }
async function f3(): MyPromise<void> { }
let f4 = async function() { }
let f5 = async function(): Promise<void> { }
let f6 = async function(): MyPromise<void> { }
let f7 = async () => { };
let f8 = async (): Promise<void> => { };
let f9 = async (): MyPromise<void> => { };
let f10 = async () => p;
let f11 = async () => mp;
let f12 = async (): Promise<number> => mp;
let f13 = async (): MyPromise<number> => p;
let o = {
async m1() { },
async m2(): Promise<void> { },
async m3(): MyPromise<void> { }
};
class C {
async m1() { }
async m2(): Promise<void> { }
async m3(): MyPromise<void> { }
static async m4() { }
static async m5(): Promise<void> { }
static async m6(): MyPromise<void> { }
}
module M {
export async function f1() { }
}
//// [asyncAwait_es6.js]
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promise, generator) {
return new Promise(function (resolve, reject) {
generator = generator.call(thisArg, _arguments);
function cast(value) { return value instanceof Promise && value.constructor === Promise ? value : new Promise(function (resolve) { resolve(value); }); }
function onfulfill(value) { try { step("next", value); } catch (e) { reject(e); } }
function onreject(value) { try { step("throw", value); } catch (e) { reject(e); } }
function step(verb, value) {
var result = generator[verb](value);
result.done ? resolve(result.value) : cast(result.value).then(onfulfill, onreject);
}
step("next", void 0);
});
};
function f0() {
return __awaiter(this, void 0, Promise, function* () { });
}
function f1() {
return __awaiter(this, void 0, Promise, function* () { });
}
function f3() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
let f4 = function () {
return __awaiter(this, void 0, Promise, function* () { });
};
let f5 = function () {
return __awaiter(this, void 0, Promise, function* () { });
};
let f6 = function () {
return __awaiter(this, void 0, MyPromise, function* () { });
};
let f7 = () => __awaiter(this, void 0, Promise, function* () { });
let f8 = () => __awaiter(this, void 0, Promise, function* () { });
let f9 = () => __awaiter(this, void 0, MyPromise, function* () { });
let f10 = () => __awaiter(this, void 0, Promise, function* () { return p; });
let f11 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
let f12 = () => __awaiter(this, void 0, Promise, function* () { return mp; });
let f13 = () => __awaiter(this, void 0, MyPromise, function* () { return p; });
let o = {
m1() {
return __awaiter(this, void 0, Promise, function* () { });
},
m2() {
return __awaiter(this, void 0, Promise, function* () { });
},
m3() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
};
class C {
m1() {
return __awaiter(this, void 0, Promise, function* () { });
}
m2() {
return __awaiter(this, void 0, Promise, function* () { });
}
m3() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
static m4() {
return __awaiter(this, void 0, Promise, function* () { });
}
static m5() {
return __awaiter(this, void 0, Promise, function* () { });
}
static m6() {
return __awaiter(this, void 0, MyPromise, function* () { });
}
}
var M;
(function (M) {
function f1() {
return __awaiter(this, void 0, Promise, function* () { });
}
M.f1 = f1;
})(M || (M = {}));

View File

@ -0,0 +1,118 @@
=== tests/cases/conformance/async/es6/asyncAwait_es6.ts ===
type MyPromise<T> = Promise<T>;
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
>T : Symbol(T, Decl(asyncAwait_es6.ts, 0, 15))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>T : Symbol(T, Decl(asyncAwait_es6.ts, 0, 15))
declare var MyPromise: typeof Promise;
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
declare var p: Promise<number>;
>p : Symbol(p, Decl(asyncAwait_es6.ts, 2, 11))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
declare var mp: MyPromise<number>;
>mp : Symbol(mp, Decl(asyncAwait_es6.ts, 3, 11))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
async function f0() { }
>f0 : Symbol(f0, Decl(asyncAwait_es6.ts, 3, 34))
async function f1(): Promise<void> { }
>f1 : Symbol(f1, Decl(asyncAwait_es6.ts, 5, 23))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
async function f3(): MyPromise<void> { }
>f3 : Symbol(f3, Decl(asyncAwait_es6.ts, 6, 38))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
let f4 = async function() { }
>f4 : Symbol(f4, Decl(asyncAwait_es6.ts, 9, 3))
let f5 = async function(): Promise<void> { }
>f5 : Symbol(f5, Decl(asyncAwait_es6.ts, 10, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
let f6 = async function(): MyPromise<void> { }
>f6 : Symbol(f6, Decl(asyncAwait_es6.ts, 11, 3))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
let f7 = async () => { };
>f7 : Symbol(f7, Decl(asyncAwait_es6.ts, 13, 3))
let f8 = async (): Promise<void> => { };
>f8 : Symbol(f8, Decl(asyncAwait_es6.ts, 14, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
let f9 = async (): MyPromise<void> => { };
>f9 : Symbol(f9, Decl(asyncAwait_es6.ts, 15, 3))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
let f10 = async () => p;
>f10 : Symbol(f10, Decl(asyncAwait_es6.ts, 16, 3))
>p : Symbol(p, Decl(asyncAwait_es6.ts, 2, 11))
let f11 = async () => mp;
>f11 : Symbol(f11, Decl(asyncAwait_es6.ts, 17, 3))
>mp : Symbol(mp, Decl(asyncAwait_es6.ts, 3, 11))
let f12 = async (): Promise<number> => mp;
>f12 : Symbol(f12, Decl(asyncAwait_es6.ts, 18, 3))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
>mp : Symbol(mp, Decl(asyncAwait_es6.ts, 3, 11))
let f13 = async (): MyPromise<number> => p;
>f13 : Symbol(f13, Decl(asyncAwait_es6.ts, 19, 3))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
>p : Symbol(p, Decl(asyncAwait_es6.ts, 2, 11))
let o = {
>o : Symbol(o, Decl(asyncAwait_es6.ts, 21, 3))
async m1() { },
>m1 : Symbol(m1, Decl(asyncAwait_es6.ts, 21, 9))
async m2(): Promise<void> { },
>m2 : Symbol(m2, Decl(asyncAwait_es6.ts, 22, 16))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
async m3(): MyPromise<void> { }
>m3 : Symbol(m3, Decl(asyncAwait_es6.ts, 23, 31))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
};
class C {
>C : Symbol(C, Decl(asyncAwait_es6.ts, 25, 2))
async m1() { }
>m1 : Symbol(m1, Decl(asyncAwait_es6.ts, 27, 9))
async m2(): Promise<void> { }
>m2 : Symbol(m2, Decl(asyncAwait_es6.ts, 28, 15))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
async m3(): MyPromise<void> { }
>m3 : Symbol(m3, Decl(asyncAwait_es6.ts, 29, 30))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
static async m4() { }
>m4 : Symbol(C.m4, Decl(asyncAwait_es6.ts, 30, 32))
static async m5(): Promise<void> { }
>m5 : Symbol(C.m5, Decl(asyncAwait_es6.ts, 31, 22))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
static async m6(): MyPromise<void> { }
>m6 : Symbol(C.m6, Decl(asyncAwait_es6.ts, 32, 37))
>MyPromise : Symbol(MyPromise, Decl(asyncAwait_es6.ts, 0, 0), Decl(asyncAwait_es6.ts, 1, 11))
}
module M {
>M : Symbol(M, Decl(asyncAwait_es6.ts, 34, 1))
export async function f1() { }
>f1 : Symbol(f1, Decl(asyncAwait_es6.ts, 36, 10))
}

View File

@ -0,0 +1,129 @@
=== tests/cases/conformance/async/es6/asyncAwait_es6.ts ===
type MyPromise<T> = Promise<T>;
>MyPromise : Promise<T>
>T : T
>Promise : Promise<T>
>T : T
declare var MyPromise: typeof Promise;
>MyPromise : PromiseConstructor
>Promise : PromiseConstructor
declare var p: Promise<number>;
>p : Promise<number>
>Promise : Promise<T>
declare var mp: MyPromise<number>;
>mp : Promise<number>
>MyPromise : Promise<T>
async function f0() { }
>f0 : () => Promise<void>
async function f1(): Promise<void> { }
>f1 : () => Promise<void>
>Promise : Promise<T>
async function f3(): MyPromise<void> { }
>f3 : () => Promise<void>
>MyPromise : Promise<T>
let f4 = async function() { }
>f4 : () => Promise<void>
>async function() { } : () => Promise<void>
let f5 = async function(): Promise<void> { }
>f5 : () => Promise<void>
>async function(): Promise<void> { } : () => Promise<void>
>Promise : Promise<T>
let f6 = async function(): MyPromise<void> { }
>f6 : () => Promise<void>
>async function(): MyPromise<void> { } : () => Promise<void>
>MyPromise : Promise<T>
let f7 = async () => { };
>f7 : () => Promise<void>
>async () => { } : () => Promise<void>
let f8 = async (): Promise<void> => { };
>f8 : () => Promise<void>
>async (): Promise<void> => { } : () => Promise<void>
>Promise : Promise<T>
let f9 = async (): MyPromise<void> => { };
>f9 : () => Promise<void>
>async (): MyPromise<void> => { } : () => Promise<void>
>MyPromise : Promise<T>
let f10 = async () => p;
>f10 : () => Promise<number>
>async () => p : () => Promise<number>
>p : Promise<number>
let f11 = async () => mp;
>f11 : () => Promise<number>
>async () => mp : () => Promise<number>
>mp : Promise<number>
let f12 = async (): Promise<number> => mp;
>f12 : () => Promise<number>
>async (): Promise<number> => mp : () => Promise<number>
>Promise : Promise<T>
>mp : Promise<number>
let f13 = async (): MyPromise<number> => p;
>f13 : () => Promise<number>
>async (): MyPromise<number> => p : () => Promise<number>
>MyPromise : Promise<T>
>p : Promise<number>
let o = {
>o : { m1(): Promise<void>; m2(): Promise<void>; m3(): Promise<void>; }
>{ async m1() { }, async m2(): Promise<void> { }, async m3(): MyPromise<void> { }} : { m1(): Promise<void>; m2(): Promise<void>; m3(): Promise<void>; }
async m1() { },
>m1 : () => Promise<void>
async m2(): Promise<void> { },
>m2 : () => Promise<void>
>Promise : Promise<T>
async m3(): MyPromise<void> { }
>m3 : () => Promise<void>
>MyPromise : Promise<T>
};
class C {
>C : C
async m1() { }
>m1 : () => Promise<void>
async m2(): Promise<void> { }
>m2 : () => Promise<void>
>Promise : Promise<T>
async m3(): MyPromise<void> { }
>m3 : () => Promise<void>
>MyPromise : Promise<T>
static async m4() { }
>m4 : () => Promise<void>
static async m5(): Promise<void> { }
>m5 : () => Promise<void>
>Promise : Promise<T>
static async m6(): MyPromise<void> { }
>m6 : () => Promise<void>
>MyPromise : Promise<T>
}
module M {
>M : typeof M
export async function f1() { }
>f1 : () => Promise<void>
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/async/es6/asyncClass_es6.ts(1,1): error TS1042: 'async' modifier cannot be used here.
==== tests/cases/conformance/async/es6/asyncClass_es6.ts (1 errors) ====
async class C {
~~~~~
!!! error TS1042: 'async' modifier cannot be used here.
}

View File

@ -0,0 +1,7 @@
//// [asyncClass_es6.ts]
async class C {
}
//// [asyncClass_es6.js]
class C {
}

View File

@ -0,0 +1,10 @@
tests/cases/conformance/async/es6/asyncConstructor_es6.ts(2,3): error TS1089: 'async' modifier cannot appear on a constructor declaration.
==== tests/cases/conformance/async/es6/asyncConstructor_es6.ts (1 errors) ====
class C {
async constructor() {
~~~~~
!!! error TS1089: 'async' modifier cannot appear on a constructor declaration.
}
}

View File

@ -0,0 +1,11 @@
//// [asyncConstructor_es6.ts]
class C {
async constructor() {
}
}
//// [asyncConstructor_es6.js]
class C {
constructor() {
}
}

View File

@ -0,0 +1,7 @@
tests/cases/conformance/async/es6/asyncDeclare_es6.ts(1,9): error TS1040: 'async' modifier cannot be used in an ambient context.
==== tests/cases/conformance/async/es6/asyncDeclare_es6.ts (1 errors) ====
declare async function foo(): Promise<void>;
~~~~~
!!! error TS1040: 'async' modifier cannot be used in an ambient context.

View File

@ -0,0 +1,4 @@
//// [asyncDeclare_es6.ts]
declare async function foo(): Promise<void>;
//// [asyncDeclare_es6.js]

View File

@ -0,0 +1,9 @@
tests/cases/conformance/async/es6/asyncEnum_es6.ts(1,1): error TS1042: 'async' modifier cannot be used here.
==== tests/cases/conformance/async/es6/asyncEnum_es6.ts (1 errors) ====
async enum E {
~~~~~
!!! error TS1042: 'async' modifier cannot be used here.
Value
}

View File

@ -0,0 +1,10 @@
//// [asyncEnum_es6.ts]
async enum E {
Value
}
//// [asyncEnum_es6.js]
var E;
(function (E) {
E[E["Value"] = 0] = "Value";
})(E || (E = {}));

View File

@ -0,0 +1,26 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,20): error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,30): error TS1109: Expression expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,33): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,33): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,38): error TS1005: ';' expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,39): error TS1128: Declaration or statement expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts(1,53): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration10_es6.ts (7 errors) ====
async function foo(a = await => await): Promise<void> {
~~~~~~~~~
!!! error TS2371: A parameter initializer is only allowed in a function or constructor implementation.
~~
!!! error TS1109: Expression expected.
~~~~~
!!! error TS1138: Parameter declaration expected.
~~~~~
!!! error TS2304: Cannot find name 'await'.
~
!!! error TS1005: ';' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration10_es6.ts]
async function foo(a = await => await): Promise<void> {
}
//// [asyncFunctionDeclaration10_es6.js]
await;
Promise < void > {};

View File

@ -0,0 +1,9 @@
//// [asyncFunctionDeclaration11_es6.ts]
async function await(): Promise<void> {
}
//// [asyncFunctionDeclaration11_es6.js]
function await() {
return __awaiter(this, void 0, Promise, function* () {
});
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration11_es6.ts ===
async function await(): Promise<void> {
>await : Symbol(await, Decl(asyncFunctionDeclaration11_es6.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration11_es6.ts ===
async function await(): Promise<void> {
>await : () => Promise<void>
>Promise : Promise<T>
}

View File

@ -0,0 +1,16 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration12_es6.ts(1,24): error TS1005: '(' expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration12_es6.ts(1,29): error TS1005: '=' expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration12_es6.ts(1,33): error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration12_es6.ts(1,47): error TS1005: '=>' expected.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration12_es6.ts (4 errors) ====
var v = async function await(): Promise<void> { }
~~~~~
!!! error TS1005: '(' expected.
~
!!! error TS1005: '=' expected.
~~~~~~~~~~~~~
!!! error TS2355: A function whose declared type is neither 'void' nor 'any' must return a value or consist of a single 'throw' statement.
~
!!! error TS1005: '=>' expected.

View File

@ -0,0 +1,5 @@
//// [asyncFunctionDeclaration12_es6.ts]
var v = async function await(): Promise<void> { }
//// [asyncFunctionDeclaration12_es6.js]
var v = , await = () => { };

View File

@ -0,0 +1,11 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration13_es6.ts(3,11): error TS2304: Cannot find name 'await'.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration13_es6.ts (1 errors) ====
async function foo(): Promise<void> {
// Legal to use 'await' in a type context.
var v: await;
~~~~~
!!! error TS2304: Cannot find name 'await'.
}

View File

@ -0,0 +1,14 @@
//// [asyncFunctionDeclaration13_es6.ts]
async function foo(): Promise<void> {
// Legal to use 'await' in a type context.
var v: await;
}
//// [asyncFunctionDeclaration13_es6.js]
function foo() {
return __awaiter(this, void 0, Promise, function* () {
// Legal to use 'await' in a type context.
var v;
});
}

View File

@ -0,0 +1,11 @@
//// [asyncFunctionDeclaration14_es6.ts]
async function foo(): Promise<void> {
return;
}
//// [asyncFunctionDeclaration14_es6.js]
function foo() {
return __awaiter(this, void 0, Promise, function* () {
return;
});
}

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration14_es6.ts ===
async function foo(): Promise<void> {
>foo : Symbol(foo, Decl(asyncFunctionDeclaration14_es6.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
return;
}

View File

@ -0,0 +1,7 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration14_es6.ts ===
async function foo(): Promise<void> {
>foo : () => Promise<void>
>Promise : Promise<T>
return;
}

View File

@ -0,0 +1,9 @@
//// [asyncFunctionDeclaration1_es6.ts]
async function foo(): Promise<void> {
}
//// [asyncFunctionDeclaration1_es6.js]
function foo() {
return __awaiter(this, void 0, Promise, function* () {
});
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1_es6.ts ===
async function foo(): Promise<void> {
>foo : Symbol(foo, Decl(asyncFunctionDeclaration1_es6.ts, 0, 0))
>Promise : Symbol(Promise, Decl(lib.d.ts, 4772, 1), Decl(lib.d.ts, 4858, 11))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration1_es6.ts ===
async function foo(): Promise<void> {
>foo : () => Promise<void>
>Promise : Promise<T>
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration2_es6.ts]
function f(await) {
}
//// [asyncFunctionDeclaration2_es6.js]
function f(await) {
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration2_es6.ts ===
function f(await) {
>f : Symbol(f, Decl(asyncFunctionDeclaration2_es6.ts, 0, 0))
>await : Symbol(await, Decl(asyncFunctionDeclaration2_es6.ts, 0, 11))
}

View File

@ -0,0 +1,5 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration2_es6.ts ===
function f(await) {
>f : (await: any) => void
>await : any
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration3_es6.ts(1,20): error TS2372: Parameter 'await' cannot be referenced in its initializer.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration3_es6.ts (1 errors) ====
function f(await = await) {
~~~~~
!!! error TS2372: Parameter 'await' cannot be referenced in its initializer.
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration3_es6.ts]
function f(await = await) {
}
//// [asyncFunctionDeclaration3_es6.js]
function f(await = await) {
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration4_es6.ts]
function await() {
}
//// [asyncFunctionDeclaration4_es6.js]
function await() {
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration4_es6.ts ===
function await() {
>await : Symbol(await, Decl(asyncFunctionDeclaration4_es6.ts, 0, 0))
}

View File

@ -0,0 +1,4 @@
=== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration4_es6.ts ===
function await() {
>await : () => void
}

View File

@ -0,0 +1,20 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,20): error TS1138: Parameter declaration expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,20): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,25): error TS1005: ';' expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,26): error TS1128: Declaration or statement expected.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts(1,40): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration5_es6.ts (5 errors) ====
async function foo(await): Promise<void> {
~~~~~
!!! error TS1138: Parameter declaration expected.
~~~~~
!!! error TS2304: Cannot find name 'await'.
~
!!! error TS1005: ';' expected.
~
!!! error TS1128: Declaration or statement expected.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,7 @@
//// [asyncFunctionDeclaration5_es6.ts]
async function foo(await): Promise<void> {
}
//// [asyncFunctionDeclaration5_es6.js]
await;
Promise < void > {};

View File

@ -0,0 +1,11 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration6_es6.ts(1,24): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration6_es6.ts(1,29): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration6_es6.ts (2 errors) ====
async function foo(a = await): Promise<void> {
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,9 @@
//// [asyncFunctionDeclaration6_es6.ts]
async function foo(a = await): Promise<void> {
}
//// [asyncFunctionDeclaration6_es6.js]
function foo(a = yield ) {
return __awaiter(this, void 0, Promise, function* () {
});
}

View File

@ -0,0 +1,14 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration7_es6.ts(3,26): error TS2524: 'await' expressions cannot be used in a parameter initializer.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration7_es6.ts(3,31): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration7_es6.ts (2 errors) ====
async function bar(): Promise<void> {
// 'await' here is an identifier, and not a yield expression.
async function foo(a = await): Promise<void> {
~~~~~
!!! error TS2524: 'await' expressions cannot be used in a parameter initializer.
~
!!! error TS1109: Expression expected.
}
}

View File

@ -0,0 +1,17 @@
//// [asyncFunctionDeclaration7_es6.ts]
async function bar(): Promise<void> {
// 'await' here is an identifier, and not a yield expression.
async function foo(a = await): Promise<void> {
}
}
//// [asyncFunctionDeclaration7_es6.js]
function bar() {
return __awaiter(this, void 0, Promise, function* () {
// 'await' here is an identifier, and not a yield expression.
function foo(a = yield ) {
return __awaiter(this, void 0, Promise, function* () {
});
}
});
}

View File

@ -0,0 +1,10 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration8_es6.ts(1,12): error TS2304: Cannot find name 'await'.
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration8_es6.ts(1,20): error TS2304: Cannot find name 'foo'.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration8_es6.ts (2 errors) ====
var v = { [await]: foo }
~~~~~
!!! error TS2304: Cannot find name 'await'.
~~~
!!! error TS2304: Cannot find name 'foo'.

View File

@ -0,0 +1,5 @@
//// [asyncFunctionDeclaration8_es6.ts]
var v = { [await]: foo }
//// [asyncFunctionDeclaration8_es6.js]
var v = { [await]: foo };

View File

@ -0,0 +1,9 @@
tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration9_es6.ts(2,19): error TS1109: Expression expected.
==== tests/cases/conformance/async/es6/functionDeclarations/asyncFunctionDeclaration9_es6.ts (1 errors) ====
async function foo(): Promise<void> {
var v = { [await]: foo }
~
!!! error TS1109: Expression expected.
}

View File

@ -0,0 +1,11 @@
//// [asyncFunctionDeclaration9_es6.ts]
async function foo(): Promise<void> {
var v = { [await]: foo }
}
//// [asyncFunctionDeclaration9_es6.js]
function foo() {
return __awaiter(this, void 0, Promise, function* () {
var v = { [yield ]: foo };
});
}

View File

@ -0,0 +1,13 @@
tests/cases/conformance/async/es6/asyncGetter_es6.ts(2,3): error TS1042: 'async' modifier cannot be used here.
tests/cases/conformance/async/es6/asyncGetter_es6.ts(2,13): error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
==== tests/cases/conformance/async/es6/asyncGetter_es6.ts (2 errors) ====
class C {
async get foo() {
~~~~~
!!! error TS1042: 'async' modifier cannot be used here.
~~~
!!! error TS2378: A 'get' accessor must return a value or consist of a single 'throw' statement.
}
}

View File

@ -0,0 +1,11 @@
//// [asyncGetter_es6.ts]
class C {
async get foo() {
}
}
//// [asyncGetter_es6.js]
class C {
get foo() {
}
}

View File

@ -0,0 +1,8 @@
tests/cases/conformance/async/es6/asyncInterface_es6.ts(1,1): error TS1042: 'async' modifier cannot be used here.
==== tests/cases/conformance/async/es6/asyncInterface_es6.ts (1 errors) ====
async interface I {
~~~~~
!!! error TS1042: 'async' modifier cannot be used here.
}

View File

@ -0,0 +1,5 @@
//// [asyncInterface_es6.ts]
async interface I {
}
//// [asyncInterface_es6.js]

Some files were not shown because too many files have changed in this diff Show More