diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 6ede08a32a4..70ca1172ccb 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -824,7 +824,7 @@ namespace ts { } // Resolves a qualified name and any involved aliases - function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, location?: Node): Symbol { + function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags): Symbol { if (nodeIsMissing(name)) { return undefined; } @@ -833,7 +833,7 @@ namespace ts { if (name.kind === SyntaxKind.Identifier) { let message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0; - symbol = resolveName(location || name, (name).text, meaning, message, name); + symbol = resolveName(name, (name).text, meaning, message, name); if (!symbol) { return undefined; } @@ -842,7 +842,7 @@ namespace ts { let left = name.kind === SyntaxKind.QualifiedName ? (name).left : (name).expression; let right = name.kind === SyntaxKind.QualifiedName ? (name).right : (name).name; - let namespace = resolveEntityName(left, SymbolFlags.Namespace, location); + let namespace = resolveEntityName(left, SymbolFlags.Namespace); if (!namespace || namespace === unknownSymbol || nodeIsMissing(right)) { return undefined; } @@ -8839,7 +8839,6 @@ namespace ts { } if (produceDiagnostics) { - checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name); checkCollisionWithArgumentsInGeneratedCode(node); if (compilerOptions.noImplicitAny && !node.type) { switch (node.kind) { @@ -9632,7 +9631,7 @@ namespace ts { * a `resolve` function as one of its arguments and results in an object with a * callable `then` signature. */ - function checkAsyncFunctionReturnType(node: SignatureDeclaration): Type { + function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type { let globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType(); if (globalPromiseConstructorLikeType === emptyObjectType) { // If we couldn't resolve the global PromiseConstructorLike type we cannot verify @@ -9640,10 +9639,10 @@ namespace ts { return unknownType; } - // The return type of an async function will be the type of the instance. For this - // to be a type compatible with our async function emit, we must also check that - // the type of the declaration (e.g. the static side or "constructor" type of the - // promise) is a compatible `PromiseConstructorLike`. + // 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): // @@ -9666,36 +9665,33 @@ namespace ts { // // 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 (...): Promise }`. - let returnType = getTypeFromTypeNode(node.type); - let entityName = getEntityNameFromTypeNode(node.type); - let resolvedName = entityName ? resolveEntityName(entityName, SymbolFlags.Value, node) : undefined; - if (!resolvedName || !returnType.symbol) { - error(node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type); - return unknownType; - } - - if (getMergedSymbol(resolvedName) !== getMergedSymbol(returnType.symbol)) { - // If we were unable to resolve the return type as a value, report an error. - let identifier = getFirstIdentifier(entityName); - error(resolvedName.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, - identifier.text, - identifier.text); - return unknownType; - } - - // When we emit the async function, we need to ensure we emit any imports that might - // otherwise have been elided if the return type were only ever referenced in a type - // position. As such, we check the entity name as an expression. - let declaredType = checkExpression(entityName); - - if (!isTypeAssignableTo(declaredType, globalPromiseConstructorLikeType)) { - // If the declared type of the return type is not assignable to a PromiseConstructorLike, report an error. - error(node, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type); - return unknownType; + + let promiseType = getTypeFromTypeNode(node.type); + 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 getAwaitedType(returnType, node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type); + return getAwaitedType(promiseType, node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type); } /** Check a decorator */ @@ -10093,22 +10089,6 @@ namespace ts { } } } - - function checkCollisionWithAwaiterVariablesInGeneratedCode(node: Node, name: DeclarationName): void { - if (!name || name.kind !== SyntaxKind.Identifier || isTypeNode(name)) { - return; - } - - let identifier = name; - let container = getContainingFunction(name); - if (container && isAsyncFunctionLike(container) && node.kind !== SyntaxKind.Identifier) { - let promiseConstructorName = getEntityNameFromTypeNode(container.type); - let firstIdentifier = promiseConstructorName ? getFirstIdentifier(promiseConstructorName) : undefined; - if (firstIdentifier && firstIdentifier.text === identifier.text) { - error(node, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, identifier.text, getTextOfNode(promiseConstructorName)); - } - } - } // Check that a parameter initializer contains no references to parameters declared to the right of itself function checkParameterInitializer(node: VariableLikeDeclaration): void { @@ -10954,7 +10934,6 @@ namespace ts { checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); - checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name); } checkTypeParameters(node.typeParameters); checkExportsOnMergedDeclarations(node); @@ -11398,7 +11377,6 @@ namespace ts { checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0); checkCollisionWithCapturedThisVariable(node, node.name); checkCollisionWithRequireExportsInGeneratedCode(node, node.name); - checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name); checkExportsOnMergedDeclarations(node); computeEnumMemberValues(node); diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index 17472e4ce85..6cd9a803aa4 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -48,6 +48,7 @@ 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." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 6ddf1709475..4ad7408d70d 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -179,6 +179,10 @@ "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 diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index d0903ccfdf2..d537380dc5d 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -49,10 +49,10 @@ var __param = (this && this.__param) || function (paramIndex, decorator) { };`; const awaiterHelper = ` -var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, PromiseConstructor) { - PromiseConstructor || (PromiseConstructor = Promise); +var __awaiter = (this && this.__awaiter) || function (args, generator) { + var PromiseConstructor = args[1] || Promise; return new PromiseConstructor(function (resolve, reject) { - generator = generator.call(thisArg, args); + generator = generator.call(args[0], args[2]); function cast(value) { return value instanceof PromiseConstructor ? value : new PromiseConstructor(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); } } @@ -3359,6 +3359,7 @@ var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, 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 @@ -3373,7 +3374,7 @@ var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, // let a = async (b) => { await b; } // // // output - // let a = (b) => __awaiter(function* (b) { + // let a = (b) => __awaiter([this], function* (b) { // yield b; // }, this); // @@ -3383,9 +3384,9 @@ var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, // let a = async (b) => { await arguments[0]; } // // // output - // let a = (b) => __awaiter(function* (arguments) { + // let a = (b) => __awaiter([this, arguments], function* (arguments) { // yield arguments[0]; - // }, this, arguments); + // }); // // The emit for an async function expression without a lexical `arguments` binding // might be: @@ -3397,7 +3398,7 @@ var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, // // // output // let a = function (b) { - // return __awaiter(function* () { + // return __awaiter([this], function* () { // yield b; // }, this); // } @@ -3412,9 +3413,24 @@ var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, // // // output // let a = function (b) { - // return __awaiter(function* (arguments) { + // return __awaiter([this, arguments], function* (arguments) { // yield arguments[0]; - // }, this, arguments); + // }); + // } + // + // 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 { + // await arguments[0]; + // } + // + // // output + // let a = function (b) { + // return __awaiter([this, arguments, MyPromise], function* (arguments) { + // yield arguments[0]; + // }); // } // @@ -3427,42 +3443,27 @@ var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, write("return"); } + write(" __awaiter([this"); + if (promiseConstructor || hasLexicalArguments) { + write(", "); + if (promiseConstructor) { + emitNodeWithoutSourceMap(promiseConstructor); + } + if (hasLexicalArguments) { + write(", arguments"); + } + } // Emit the call to __awaiter. - let hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0; if (hasLexicalArguments) { - write(" __awaiter(function* (arguments)"); + write("], function* (arguments)"); } else { - write(" __awaiter(function* ()"); + write("], function* ()"); } // Emit the signature and body for the inner generator function. emitFunctionBody(node); - - // Emit the current `this` binding. - write(","); - writeLine(); - write("this"); - - // Optionally emit the lexical arguments. - if (hasLexicalArguments) { - write(", arguments"); - } - - // If the function has an explicit type annotation for a promise, emit the - // constructor. - if (promiseConstructor) { - // If we did not have lexical arguments, supply undefined (void 0) for - // the `arguments` parameter. - if (!hasLexicalArguments) { - write(", void 0"); - } - - write(", "); - emitNodeWithoutSourceMap(promiseConstructor); - } - write(")"); // If this is not an async arrow, emit the closing brace of the outer function body. diff --git a/tests/baselines/reference/asyncArrowFunction1_es6.js b/tests/baselines/reference/asyncArrowFunction1_es6.js index 257b147dbc7..2c2f1091b15 100644 --- a/tests/baselines/reference/asyncArrowFunction1_es6.js +++ b/tests/baselines/reference/asyncArrowFunction1_es6.js @@ -4,6 +4,5 @@ var foo = async (): Promise => { }; //// [asyncArrowFunction1_es6.js] -var foo = () => __awaiter(function* () { -}, -this, void 0, Promise); +var foo = () => __awaiter([this, Promise], function* () { +}); diff --git a/tests/baselines/reference/asyncArrowFunction6_es6.js b/tests/baselines/reference/asyncArrowFunction6_es6.js index 5353903d10e..0a39441edf7 100644 --- a/tests/baselines/reference/asyncArrowFunction6_es6.js +++ b/tests/baselines/reference/asyncArrowFunction6_es6.js @@ -4,6 +4,5 @@ var foo = async (a = await): Promise => { } //// [asyncArrowFunction6_es6.js] -var foo = (a = yield ) => __awaiter(function* () { -}, -this, void 0, Promise); +var foo = (a = yield ) => __awaiter([this, Promise], function* () { +}); diff --git a/tests/baselines/reference/asyncArrowFunction7_es6.js b/tests/baselines/reference/asyncArrowFunction7_es6.js index b3c5f536550..bb17963bfd3 100644 --- a/tests/baselines/reference/asyncArrowFunction7_es6.js +++ b/tests/baselines/reference/asyncArrowFunction7_es6.js @@ -7,10 +7,8 @@ var bar = async (): Promise => { } //// [asyncArrowFunction7_es6.js] -var bar = () => __awaiter(function* () { +var bar = () => __awaiter([this, Promise], function* () { // 'await' here is an identifier, and not an await expression. - var foo = (a = yield ) => __awaiter(function* () { - }, - this, void 0, Promise); -}, -this, void 0, Promise); + var foo = (a = yield ) => __awaiter([this, Promise], function* () { + }); +}); diff --git a/tests/baselines/reference/asyncArrowFunction8_es6.js b/tests/baselines/reference/asyncArrowFunction8_es6.js index e4383a16220..2ec23259510 100644 --- a/tests/baselines/reference/asyncArrowFunction8_es6.js +++ b/tests/baselines/reference/asyncArrowFunction8_es6.js @@ -5,7 +5,6 @@ var foo = async (): Promise => { } //// [asyncArrowFunction8_es6.js] -var foo = () => __awaiter(function* () { +var foo = () => __awaiter([this, Promise], function* () { var v = { [yield ]: foo }; -}, -this, void 0, Promise); +}); diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.js b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.js index 888c935cc3f..8cac736ea1b 100644 --- a/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.js +++ b/tests/baselines/reference/asyncArrowFunctionCapturesArguments_es6.js @@ -11,7 +11,6 @@ class C { class C { method() { function other() { } - var fn = () => __awaiter(function* (arguments) { return yield other.apply(this, arguments); }, - this, arguments); + var fn = () => __awaiter([this, , arguments], function* (arguments) { return yield other.apply(this, arguments); }); } } diff --git a/tests/baselines/reference/asyncArrowFunctionCapturesThis_es6.js b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es6.js index 67279d7f1be..b13815ffcbf 100644 --- a/tests/baselines/reference/asyncArrowFunctionCapturesThis_es6.js +++ b/tests/baselines/reference/asyncArrowFunctionCapturesThis_es6.js @@ -9,7 +9,6 @@ class C { //// [asyncArrowFunctionCapturesThis_es6.js] class C { method() { - var fn = () => __awaiter(function* () { return yield this; }, - this); + var fn = () => __awaiter([this], function* () { return yield this; }); } } diff --git a/tests/baselines/reference/asyncAwait_es6.js b/tests/baselines/reference/asyncAwait_es6.js new file mode 100644 index 00000000000..2c0ffaf478a --- /dev/null +++ b/tests/baselines/reference/asyncAwait_es6.js @@ -0,0 +1,119 @@ +//// [asyncAwait_es6.ts] +type MyPromise = Promise; +declare var MyPromise: typeof Promise; +declare var p: Promise; +declare var mp: MyPromise; + +async function f0() { } +async function f1(): Promise { } +async function f3(): MyPromise { } + +let f4 = async function() { } +let f5 = async function(): Promise { } +let f6 = async function(): MyPromise { } + +let f7 = async () => { }; +let f8 = async (): Promise => { }; +let f9 = async (): MyPromise => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async (): Promise => mp; +let f13 = async (): MyPromise => p; + +let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } +}; + +class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } +} + +module M { + export async function f1() { } +} + +//// [asyncAwait_es6.js] +var __awaiter = (this && this.__awaiter) || function (args, generator) { + var PromiseConstructor = args[1] || Promise; + return new PromiseConstructor(function (resolve, reject) { + generator = generator.call(args[0], args[2]); + function cast(value) { return value instanceof PromiseConstructor ? value : new PromiseConstructor(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], function* () { }); +} +function f1() { + return __awaiter([this, Promise], function* () { }); +} +function f3() { + return __awaiter([this, MyPromise], function* () { }); +} +let f4 = function () { + return __awaiter([this], function* () { }); +}; +let f5 = function () { + return __awaiter([this, Promise], function* () { }); +}; +let f6 = function () { + return __awaiter([this, MyPromise], function* () { }); +}; +let f7 = () => __awaiter([this], function* () { }); +let f8 = () => __awaiter([this, Promise], function* () { }); +let f9 = () => __awaiter([this, MyPromise], function* () { }); +let f10 = () => __awaiter([this], function* () { return p; }); +let f11 = () => __awaiter([this], function* () { return mp; }); +let f12 = () => __awaiter([this, Promise], function* () { return mp; }); +let f13 = () => __awaiter([this, MyPromise], function* () { return p; }); +let o = { + m1() { + return __awaiter([this], function* () { }); + }, + m2() { + return __awaiter([this, Promise], function* () { }); + }, + m3() { + return __awaiter([this, MyPromise], function* () { }); + } +}; +class C { + m1() { + return __awaiter([this], function* () { }); + } + m2() { + return __awaiter([this, Promise], function* () { }); + } + m3() { + return __awaiter([this, MyPromise], function* () { }); + } + static m4() { + return __awaiter([this], function* () { }); + } + static m5() { + return __awaiter([this, Promise], function* () { }); + } + static m6() { + return __awaiter([this, MyPromise], function* () { }); + } +} +var M; +(function (M) { + function f1() { + return __awaiter([this], function* () { }); + } + M.f1 = f1; +})(M || (M = {})); diff --git a/tests/baselines/reference/asyncAwait_es6.symbols b/tests/baselines/reference/asyncAwait_es6.symbols new file mode 100644 index 00000000000..6cd18e254ba --- /dev/null +++ b/tests/baselines/reference/asyncAwait_es6.symbols @@ -0,0 +1,118 @@ +=== tests/cases/conformance/async/es6/asyncAwait_es6.ts === +type MyPromise = Promise; +>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, 4768, 1), Decl(lib.d.ts, 4854, 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, 4768, 1), Decl(lib.d.ts, 4854, 11)) + +declare var p: Promise; +>p : Symbol(p, Decl(asyncAwait_es6.ts, 2, 11)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + +declare var mp: MyPromise; +>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 { } +>f1 : Symbol(f1, Decl(asyncAwait_es6.ts, 5, 23)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + +async function f3(): MyPromise { } +>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 { } +>f5 : Symbol(f5, Decl(asyncAwait_es6.ts, 10, 3)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + +let f6 = async function(): MyPromise { } +>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 => { }; +>f8 : Symbol(f8, Decl(asyncAwait_es6.ts, 14, 3)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + +let f9 = async (): MyPromise => { }; +>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 => mp; +>f12 : Symbol(f12, Decl(asyncAwait_es6.ts, 18, 3)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) +>mp : Symbol(mp, Decl(asyncAwait_es6.ts, 3, 11)) + +let f13 = async (): MyPromise => 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 { }, +>m2 : Symbol(m2, Decl(asyncAwait_es6.ts, 22, 16)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + + async m3(): MyPromise { } +>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 { } +>m2 : Symbol(m2, Decl(asyncAwait_es6.ts, 28, 15)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + + async m3(): MyPromise { } +>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 { } +>m5 : Symbol(C.m5, Decl(asyncAwait_es6.ts, 31, 22)) +>Promise : Symbol(Promise, Decl(lib.d.ts, 4768, 1), Decl(lib.d.ts, 4854, 11)) + + static async m6(): MyPromise { } +>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)) +} diff --git a/tests/baselines/reference/asyncAwait_es6.types b/tests/baselines/reference/asyncAwait_es6.types new file mode 100644 index 00000000000..5f0cd2cc35a --- /dev/null +++ b/tests/baselines/reference/asyncAwait_es6.types @@ -0,0 +1,129 @@ +=== tests/cases/conformance/async/es6/asyncAwait_es6.ts === +type MyPromise = Promise; +>MyPromise : Promise +>T : T +>Promise : Promise +>T : T + +declare var MyPromise: typeof Promise; +>MyPromise : PromiseConstructor +>Promise : PromiseConstructor + +declare var p: Promise; +>p : Promise +>Promise : Promise + +declare var mp: MyPromise; +>mp : Promise +>MyPromise : Promise + +async function f0() { } +>f0 : () => Promise + +async function f1(): Promise { } +>f1 : () => Promise +>Promise : Promise + +async function f3(): MyPromise { } +>f3 : () => Promise +>MyPromise : Promise + +let f4 = async function() { } +>f4 : () => Promise +>async function() { } : () => Promise + +let f5 = async function(): Promise { } +>f5 : () => Promise +>async function(): Promise { } : () => Promise +>Promise : Promise + +let f6 = async function(): MyPromise { } +>f6 : () => Promise +>async function(): MyPromise { } : () => Promise +>MyPromise : Promise + +let f7 = async () => { }; +>f7 : () => Promise +>async () => { } : () => Promise + +let f8 = async (): Promise => { }; +>f8 : () => Promise +>async (): Promise => { } : () => Promise +>Promise : Promise + +let f9 = async (): MyPromise => { }; +>f9 : () => Promise +>async (): MyPromise => { } : () => Promise +>MyPromise : Promise + +let f10 = async () => p; +>f10 : () => Promise +>async () => p : () => Promise +>p : Promise + +let f11 = async () => mp; +>f11 : () => Promise +>async () => mp : () => Promise +>mp : Promise + +let f12 = async (): Promise => mp; +>f12 : () => Promise +>async (): Promise => mp : () => Promise +>Promise : Promise +>mp : Promise + +let f13 = async (): MyPromise => p; +>f13 : () => Promise +>async (): MyPromise => p : () => Promise +>MyPromise : Promise +>p : Promise + +let o = { +>o : { m1(): Promise; m2(): Promise; m3(): Promise; } +>{ async m1() { }, async m2(): Promise { }, async m3(): MyPromise { }} : { m1(): Promise; m2(): Promise; m3(): Promise; } + + async m1() { }, +>m1 : () => Promise + + async m2(): Promise { }, +>m2 : () => Promise +>Promise : Promise + + async m3(): MyPromise { } +>m3 : () => Promise +>MyPromise : Promise + +}; + +class C { +>C : C + + async m1() { } +>m1 : () => Promise + + async m2(): Promise { } +>m2 : () => Promise +>Promise : Promise + + async m3(): MyPromise { } +>m3 : () => Promise +>MyPromise : Promise + + static async m4() { } +>m4 : () => Promise + + static async m5(): Promise { } +>m5 : () => Promise +>Promise : Promise + + static async m6(): MyPromise { } +>m6 : () => Promise +>MyPromise : Promise +} + +module M { +>M : typeof M + + export async function f1() { } +>f1 : () => Promise +} diff --git a/tests/baselines/reference/asyncFunctionDeclaration11_es6.js b/tests/baselines/reference/asyncFunctionDeclaration11_es6.js index dbf2d489a92..7cc10548371 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration11_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration11_es6.js @@ -4,7 +4,6 @@ async function await(): Promise { //// [asyncFunctionDeclaration11_es6.js] function await() { - return __awaiter(function* () { - }, - this, void 0, Promise); + return __awaiter([this, Promise], function* () { + }); } diff --git a/tests/baselines/reference/asyncFunctionDeclaration13_es6.js b/tests/baselines/reference/asyncFunctionDeclaration13_es6.js index 35f6af6b2ff..f17b5c894f8 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration13_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration13_es6.js @@ -7,9 +7,8 @@ async function foo(): Promise { //// [asyncFunctionDeclaration13_es6.js] function foo() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { // Legal to use 'await' in a type context. var v; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/asyncFunctionDeclaration14_es6.js b/tests/baselines/reference/asyncFunctionDeclaration14_es6.js index 3610cabbdec..7fee3f4802a 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration14_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration14_es6.js @@ -5,8 +5,7 @@ async function foo(): Promise { //// [asyncFunctionDeclaration14_es6.js] function foo() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { return; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/asyncFunctionDeclaration1_es6.js b/tests/baselines/reference/asyncFunctionDeclaration1_es6.js index e3e1fb65096..3e587858021 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration1_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration1_es6.js @@ -4,7 +4,6 @@ async function foo(): Promise { //// [asyncFunctionDeclaration1_es6.js] function foo() { - return __awaiter(function* () { - }, - this, void 0, Promise); + return __awaiter([this, Promise], function* () { + }); } diff --git a/tests/baselines/reference/asyncFunctionDeclaration6_es6.js b/tests/baselines/reference/asyncFunctionDeclaration6_es6.js index 3c1b16cea96..33645996cd8 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration6_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration6_es6.js @@ -4,7 +4,6 @@ async function foo(a = await): Promise { //// [asyncFunctionDeclaration6_es6.js] function foo(a = yield ) { - return __awaiter(function* () { - }, - this, void 0, Promise); + return __awaiter([this, Promise], function* () { + }); } diff --git a/tests/baselines/reference/asyncFunctionDeclaration7_es6.js b/tests/baselines/reference/asyncFunctionDeclaration7_es6.js index 0b2f643e469..667250e45db 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration7_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration7_es6.js @@ -7,13 +7,11 @@ async function bar(): Promise { //// [asyncFunctionDeclaration7_es6.js] function bar() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { // 'await' here is an identifier, and not a yield expression. function foo(a = yield ) { - return __awaiter(function* () { - }, - this, void 0, Promise); + return __awaiter([this, Promise], function* () { + }); } - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/asyncFunctionDeclaration9_es6.js b/tests/baselines/reference/asyncFunctionDeclaration9_es6.js index 7f23510f942..dab1b75076e 100644 --- a/tests/baselines/reference/asyncFunctionDeclaration9_es6.js +++ b/tests/baselines/reference/asyncFunctionDeclaration9_es6.js @@ -5,8 +5,7 @@ async function foo(): Promise { //// [asyncFunctionDeclaration9_es6.js] function foo() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { var v = { [yield ]: foo }; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitBinaryExpression1_es6.js b/tests/baselines/reference/awaitBinaryExpression1_es6.js index 0531f7643fc..11b630355d4 100644 --- a/tests/baselines/reference/awaitBinaryExpression1_es6.js +++ b/tests/baselines/reference/awaitBinaryExpression1_es6.js @@ -9,10 +9,9 @@ async function func(): Promise { //// [awaitBinaryExpression1_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = (yield p) || a; "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitBinaryExpression2_es6.js b/tests/baselines/reference/awaitBinaryExpression2_es6.js index 36545440f1f..e8f610ae10a 100644 --- a/tests/baselines/reference/awaitBinaryExpression2_es6.js +++ b/tests/baselines/reference/awaitBinaryExpression2_es6.js @@ -9,10 +9,9 @@ async function func(): Promise { //// [awaitBinaryExpression2_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = (yield p) && a; "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitBinaryExpression3_es6.js b/tests/baselines/reference/awaitBinaryExpression3_es6.js index bfe95956ebc..770bf75d5a1 100644 --- a/tests/baselines/reference/awaitBinaryExpression3_es6.js +++ b/tests/baselines/reference/awaitBinaryExpression3_es6.js @@ -9,10 +9,9 @@ async function func(): Promise { //// [awaitBinaryExpression3_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = (yield p) + a; "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitBinaryExpression4_es6.js b/tests/baselines/reference/awaitBinaryExpression4_es6.js index fa2dd17143e..f756d6604bb 100644 --- a/tests/baselines/reference/awaitBinaryExpression4_es6.js +++ b/tests/baselines/reference/awaitBinaryExpression4_es6.js @@ -9,10 +9,9 @@ async function func(): Promise { //// [awaitBinaryExpression4_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = yield p, a; "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitBinaryExpression5_es6.js b/tests/baselines/reference/awaitBinaryExpression5_es6.js index 615320e8ebb..c66cfbbd57a 100644 --- a/tests/baselines/reference/awaitBinaryExpression5_es6.js +++ b/tests/baselines/reference/awaitBinaryExpression5_es6.js @@ -10,11 +10,10 @@ async function func(): Promise { //// [awaitBinaryExpression5_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var o; o.a = yield p; "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression1_es6.js b/tests/baselines/reference/awaitCallExpression1_es6.js index 9e329e14ad2..db4e0c96abf 100644 --- a/tests/baselines/reference/awaitCallExpression1_es6.js +++ b/tests/baselines/reference/awaitCallExpression1_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression1_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = fn(a, a, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression2_es6.js b/tests/baselines/reference/awaitCallExpression2_es6.js index 4f8e088b55d..47b1e062ae5 100644 --- a/tests/baselines/reference/awaitCallExpression2_es6.js +++ b/tests/baselines/reference/awaitCallExpression2_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression2_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = fn(yield p, a, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression3_es6.js b/tests/baselines/reference/awaitCallExpression3_es6.js index 54b5d8411d7..e7a09f9b9b8 100644 --- a/tests/baselines/reference/awaitCallExpression3_es6.js +++ b/tests/baselines/reference/awaitCallExpression3_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression3_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = fn(a, yield p, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression4_es6.js b/tests/baselines/reference/awaitCallExpression4_es6.js index 9e32395df83..59449e4f6a1 100644 --- a/tests/baselines/reference/awaitCallExpression4_es6.js +++ b/tests/baselines/reference/awaitCallExpression4_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression4_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = (yield pfn)(a, a, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression5_es6.js b/tests/baselines/reference/awaitCallExpression5_es6.js index 76ccf06b105..c5e28deee89 100644 --- a/tests/baselines/reference/awaitCallExpression5_es6.js +++ b/tests/baselines/reference/awaitCallExpression5_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression5_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = o.fn(a, a, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression6_es6.js b/tests/baselines/reference/awaitCallExpression6_es6.js index 90b96a06ad7..62fde8c799c 100644 --- a/tests/baselines/reference/awaitCallExpression6_es6.js +++ b/tests/baselines/reference/awaitCallExpression6_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression6_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = o.fn(yield p, a, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression7_es6.js b/tests/baselines/reference/awaitCallExpression7_es6.js index e9a2edb8a91..f717d76c51d 100644 --- a/tests/baselines/reference/awaitCallExpression7_es6.js +++ b/tests/baselines/reference/awaitCallExpression7_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression7_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = o.fn(a, yield p, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/baselines/reference/awaitCallExpression8_es6.js b/tests/baselines/reference/awaitCallExpression8_es6.js index e172dde417d..e6e2cee172b 100644 --- a/tests/baselines/reference/awaitCallExpression8_es6.js +++ b/tests/baselines/reference/awaitCallExpression8_es6.js @@ -13,10 +13,9 @@ async function func(): Promise { //// [awaitCallExpression8_es6.js] function func() { - return __awaiter(function* () { + return __awaiter([this, Promise], function* () { "before"; var b = (yield po).fn(a, a, a); "after"; - }, - this, void 0, Promise); + }); } diff --git a/tests/cases/conformance/async/es6/asyncAwait_es6.ts b/tests/cases/conformance/async/es6/asyncAwait_es6.ts new file mode 100644 index 00000000000..8e72197a98d --- /dev/null +++ b/tests/cases/conformance/async/es6/asyncAwait_es6.ts @@ -0,0 +1,40 @@ +// @target: ES6 +type MyPromise = Promise; +declare var MyPromise: typeof Promise; +declare var p: Promise; +declare var mp: MyPromise; + +async function f0() { } +async function f1(): Promise { } +async function f3(): MyPromise { } + +let f4 = async function() { } +let f5 = async function(): Promise { } +let f6 = async function(): MyPromise { } + +let f7 = async () => { }; +let f8 = async (): Promise => { }; +let f9 = async (): MyPromise => { }; +let f10 = async () => p; +let f11 = async () => mp; +let f12 = async (): Promise => mp; +let f13 = async (): MyPromise => p; + +let o = { + async m1() { }, + async m2(): Promise { }, + async m3(): MyPromise { } +}; + +class C { + async m1() { } + async m2(): Promise { } + async m3(): MyPromise { } + static async m4() { } + static async m5(): Promise { } + static async m6(): MyPromise { } +} + +module M { + export async function f1() { } +} \ No newline at end of file