mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-02-10 15:25:54 -06:00
Updated emit to align with current proposal for ES7 async functions
This commit is contained in:
parent
9560d6f1e9
commit
72a6865f93
@ -824,7 +824,7 @@ module ts {
|
||||
}
|
||||
|
||||
// Resolves a qualified name and any involved aliases
|
||||
function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags): Symbol {
|
||||
function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, location?: Node): Symbol {
|
||||
if (nodeIsMissing(name)) {
|
||||
return undefined;
|
||||
}
|
||||
@ -833,7 +833,7 @@ module ts {
|
||||
if (name.kind === SyntaxKind.Identifier) {
|
||||
let message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
|
||||
|
||||
symbol = resolveName(name, (<Identifier>name).text, meaning, message, <Identifier>name);
|
||||
symbol = resolveName(location || name, (<Identifier>name).text, meaning, message, <Identifier>name);
|
||||
if (!symbol) {
|
||||
return undefined;
|
||||
}
|
||||
@ -842,7 +842,7 @@ module ts {
|
||||
let left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessExpression>name).expression;
|
||||
let right = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).right : (<PropertyAccessExpression>name).name;
|
||||
|
||||
let namespace = resolveEntityName(left, SymbolFlags.Namespace);
|
||||
let namespace = resolveEntityName(left, SymbolFlags.Namespace, location);
|
||||
if (!namespace || namespace === unknownSymbol || nodeIsMissing(right)) {
|
||||
return undefined;
|
||||
}
|
||||
@ -3834,6 +3834,20 @@ module ts {
|
||||
}
|
||||
return links.resolvedType;
|
||||
}
|
||||
|
||||
function getEntityNameFromTypeNode(node: TypeNode): EntityName | Expression {
|
||||
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);
|
||||
default:
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeFromTypeNode(node: TypeNode): Type {
|
||||
switch (node.kind) {
|
||||
@ -5643,9 +5657,10 @@ module ts {
|
||||
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);
|
||||
}
|
||||
else if (node.parserContextFlags & ParserContextFlags.Await) {
|
||||
error(node, Diagnostics.The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_function_expression);
|
||||
}
|
||||
}
|
||||
|
||||
if (node.parserContextFlags & ParserContextFlags.Await) {
|
||||
getNodeLinks(container).flags |= NodeCheckFlags.CaptureArguments;
|
||||
}
|
||||
}
|
||||
|
||||
@ -7746,11 +7761,14 @@ module ts {
|
||||
Debug.assert(node.kind !== SyntaxKind.MethodDeclaration || isObjectLiteralMethod(node));
|
||||
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
emitAwaiter = true;
|
||||
}
|
||||
|
||||
let returnType = node.type && getTypeFromTypeNode(node.type);
|
||||
|
||||
let promisedType: Type;
|
||||
if (returnType && isAsync) {
|
||||
promisedType = checkAsyncFunctionReturnType(node, returnType);
|
||||
promisedType = checkAsyncFunctionReturnType(node);
|
||||
}
|
||||
|
||||
if (returnType && !node.asteriskToken) {
|
||||
@ -9440,56 +9458,71 @@ module ts {
|
||||
* a `resolve` function as one of its arguments and results in an object with a
|
||||
* callable `then` signature.
|
||||
*/
|
||||
function checkAsyncFunctionReturnType(node: SignatureDeclaration, returnType: Type): Type {
|
||||
function checkAsyncFunctionReturnType(node: SignatureDeclaration): Type {
|
||||
let globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
|
||||
if (globalPromiseConstructorLikeType !== emptyObjectType) {
|
||||
// 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`.
|
||||
//
|
||||
// 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 declaredType = returnType.symbol ? getTypeOfSymbol(returnType.symbol) : emptyObjectType;
|
||||
if (isTypeAssignableTo(declaredType, globalPromiseConstructorLikeType)) {
|
||||
// Ensure we will emit the `__awaiter` helper.
|
||||
emitAwaiter = true;
|
||||
if (globalPromiseConstructorLikeType === emptyObjectType) {
|
||||
// If we couldn't resolve the global PromiseConstructorLike type we cannot verify
|
||||
// compatibility with __awaiter, so we report an error.
|
||||
error(node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
|
||||
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 get the entity name of the type reference from the return
|
||||
// type and check it as an expression.
|
||||
let promiseConstructor = getPromiseConstructor(node);
|
||||
if (promiseConstructor) {
|
||||
checkExpressionOrQualifiedName(promiseConstructor);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
// 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`.
|
||||
//
|
||||
// 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 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 = checkExpressionOrQualifiedName(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;
|
||||
}
|
||||
|
||||
error(node, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
|
||||
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);
|
||||
}
|
||||
|
||||
/** Check a decorator */
|
||||
@ -9635,6 +9668,10 @@ module ts {
|
||||
checkGrammarDeclarationNameInStrictMode(node);
|
||||
checkDecorators(node);
|
||||
checkSignatureDeclaration(node);
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync) {
|
||||
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
|
||||
@ -9670,10 +9707,9 @@ module ts {
|
||||
checkSourceElement(node.body);
|
||||
if (node.type && !isAccessor(node.kind) && !node.asteriskToken) {
|
||||
let returnType = getTypeFromTypeNode(node.type);
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
let promisedType: Type;
|
||||
if (isAsync) {
|
||||
promisedType = checkAsyncFunctionReturnType(node, returnType);
|
||||
promisedType = checkAsyncFunctionReturnType(node);
|
||||
}
|
||||
|
||||
checkIfNonVoidFunctionHasReturnExpressionsOrSingleThrowStatment(node, isAsync ? promisedType : returnType);
|
||||
@ -9888,13 +9924,11 @@ module ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getPromiseConstructor(node: SignatureDeclaration): EntityName {
|
||||
if (isAsyncFunctionLike(node)) {
|
||||
function getPromiseConstructor(node: SignatureDeclaration): EntityName | Expression {
|
||||
if (isAsyncFunctionLike(node) && node.type) {
|
||||
let links = getNodeLinks(node);
|
||||
if (!links.promiseConstructor) {
|
||||
if (node.type && node.type.kind === SyntaxKind.TypeReference) {
|
||||
links.promiseConstructor = (<TypeReferenceNode>node.type).typeName;
|
||||
}
|
||||
links.promiseConstructor = getEntityNameFromTypeNode(node.type);
|
||||
}
|
||||
|
||||
return links.promiseConstructor;
|
||||
@ -10037,8 +10071,12 @@ module ts {
|
||||
function checkGrammarDisallowedModifiersInBlockOrObjectLiteralExpression(node: Node) {
|
||||
if (node.modifiers) {
|
||||
if (inBlockOrObjectLiteralExpression(node)) {
|
||||
// disallow all but the `async` modifier here
|
||||
if (isAccessor(node.kind) || !isFunctionLike(node) || (node.modifiers.flags & ~NodeFlags.Async)) {
|
||||
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);
|
||||
}
|
||||
}
|
||||
@ -12973,10 +13011,15 @@ module 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);
|
||||
|
||||
@ -49,19 +49,20 @@ var __param = (this && this.__param) || function (paramIndex, decorator) {
|
||||
};`;
|
||||
|
||||
const awaiterHelper = `
|
||||
var __awaiter = (this && this.__awaiter) || function (generator, ctor) {
|
||||
function resolve(value) { return step(generator.next(value)); }
|
||||
function reject(reason) { return step(generator["throw"](reason)); }
|
||||
function step(result) {
|
||||
while (true) {
|
||||
var done = result.done, value = result.value, then;
|
||||
if (done) return value;
|
||||
if (value && typeof (then = value.then) === "function") return then.call(value, resolve, reject);
|
||||
result = generator.next(value);
|
||||
var __awaiter = (this && this.__awaiter) || function (generator, thisArg, args, PromiseConstructor) {
|
||||
PromiseConstructor || (PromiseConstructor = Promise);
|
||||
return new PromiseConstructor(function (resolve, reject) {
|
||||
generator = generator.call(thisArg, args);
|
||||
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);
|
||||
}
|
||||
}
|
||||
return new (ctor || Promise)(function (resolver) { resolver(resolve(undefined)); });
|
||||
}`;
|
||||
step("next", void 0);
|
||||
});
|
||||
};`;
|
||||
|
||||
let compilerOptions = host.getCompilerOptions();
|
||||
let languageVersion = compilerOptions.target || ScriptTarget.ES3;
|
||||
@ -128,7 +129,7 @@ var __awaiter = (this && this.__awaiter) || function (generator, ctor) {
|
||||
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>) {...})
|
||||
@ -3390,100 +3391,114 @@ var __awaiter = (this && this.__awaiter) || function (generator, ctor) {
|
||||
emitSignatureParameters(node);
|
||||
}
|
||||
|
||||
function emitAsyncSignatureAndBodyForES6(node: FunctionLikeDeclaration) {
|
||||
function emitAsyncFunctionBodyForES6(node: FunctionLikeDeclaration) {
|
||||
let promiseConstructor = resolver.getPromiseConstructor(node);
|
||||
let isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
|
||||
let args: string;
|
||||
|
||||
// An async function is emit as an outer function that calls an inner
|
||||
// generator function. Any arguments of the outer function must be
|
||||
// evaluated in the context of the generator function, to ensure the correct
|
||||
// environment and bindings for things like binding patterns in the
|
||||
// argument list.
|
||||
// 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.
|
||||
//
|
||||
// For async function declarations and function expressions, we want to
|
||||
// pass the `arguments` object of the outer function to the inner generator
|
||||
// function in the event the async function directly manipulates the `arguments`
|
||||
// object.
|
||||
// The emit for an async arrow without a lexical `arguments` binding might be:
|
||||
//
|
||||
// For async arrow functions, the `arguments` object is not bound to the arrow
|
||||
// but its containing function. In that case, we must collect all of the passed
|
||||
// arguments into an array which we then pass to the inner generator function to
|
||||
// ensure the correct environment for any binding patterns.
|
||||
// // input
|
||||
// let a = async (b) => { await b; }
|
||||
//
|
||||
// Async arrow functions do not have access to the lexical `arguments` of its
|
||||
// lexical container.
|
||||
// // output
|
||||
// let a = (b) => __awaiter(function* (b) {
|
||||
// yield b;
|
||||
// }, this);
|
||||
//
|
||||
// The emit for an async arrow without parameters will look something like this:
|
||||
// The emit for an async arrow with a lexical `arguments` binding might be:
|
||||
//
|
||||
// let a = async () => await b;
|
||||
// // input
|
||||
// let a = async (b) => { await arguments[0]; }
|
||||
//
|
||||
// let a = () => __awaiter(function* () {
|
||||
// return yield b;
|
||||
// }.apply(this));
|
||||
// // output
|
||||
// let a = (b) => __awaiter(function* (arguments) {
|
||||
// yield arguments[0];
|
||||
// }, this, arguments);
|
||||
//
|
||||
// The emit for an async arrow with parameters will look something like this:
|
||||
// The emit for an async function expression without a lexical `arguments` binding
|
||||
// might be:
|
||||
//
|
||||
// let a = async (b) => await b;
|
||||
//
|
||||
// let a = (...arguments_1) => __awaiter(function* (b) {
|
||||
// return yield b;
|
||||
// }).apply(this, arguments_1);
|
||||
//
|
||||
// The emit for an async function expression will look something like this:
|
||||
//
|
||||
// let a = async function () {
|
||||
// return await b;
|
||||
// // input
|
||||
// let a = async function (b) {
|
||||
// await b;
|
||||
// }
|
||||
//
|
||||
// let a = function () {
|
||||
// // output
|
||||
// let a = function (b) {
|
||||
// return __awaiter(function* () {
|
||||
// return yield b;
|
||||
// }.apply(this, arguments));
|
||||
// yield b;
|
||||
// }, this);
|
||||
// }
|
||||
//
|
||||
if (isArrowFunction) {
|
||||
// Emit the outer signature for the async arrow
|
||||
if (node.parameters.length) {
|
||||
args = makeUniqueName("arguments");
|
||||
write(`(...${args}) => `);
|
||||
}
|
||||
else {
|
||||
write("() => ");
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Emit the outer signature for the async function expression or declaration
|
||||
args = "arguments";
|
||||
write("() {");
|
||||
// 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(function* (arguments) {
|
||||
// yield arguments[0];
|
||||
// }, this, arguments);
|
||||
// }
|
||||
//
|
||||
|
||||
// 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("return");
|
||||
}
|
||||
|
||||
// Emit the call to __awaiter
|
||||
write("__awaiter(function *");
|
||||
|
||||
// Emit the signature and body for the inner generator function
|
||||
emitSignatureParameters(node);
|
||||
// Emit the call to __awaiter.
|
||||
let hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
|
||||
if (hasLexicalArguments) {
|
||||
write(" __awaiter(function* (arguments)");
|
||||
}
|
||||
else {
|
||||
write(" __awaiter(function* ()");
|
||||
}
|
||||
|
||||
// Emit the signature and body for the inner generator function.
|
||||
emitFunctionBody(node);
|
||||
|
||||
// Emit the call to `apply` to ensure the correct `this` and arguments.
|
||||
write(".apply(this");
|
||||
if (args) {
|
||||
write(`, ${args}`);
|
||||
}
|
||||
write(")");
|
||||
// Emit the current `this` binding.
|
||||
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(", ");
|
||||
emit(promiseConstructor);
|
||||
emitNodeWithoutSourceMap(promiseConstructor);
|
||||
}
|
||||
|
||||
write(")");
|
||||
|
||||
// If this is not an async arrow, emit the closing brace of the outer function body
|
||||
// If this is not an async arrow, emit the closing brace of the outer function body.
|
||||
if (!isArrowFunction) {
|
||||
write(";");
|
||||
decreaseIndent();
|
||||
@ -3516,20 +3531,20 @@ var __awaiter = (this && this.__awaiter) || function (generator, ctor) {
|
||||
tempVariables = undefined;
|
||||
tempParameters = undefined;
|
||||
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync && languageVersion === ScriptTarget.ES6) {
|
||||
emitAsyncSignatureAndBodyForES6(node);
|
||||
// When targeting ES6, emit arrow function natively in ES6
|
||||
if (shouldEmitAsArrowFunction(node)) {
|
||||
emitSignatureParametersForArrow(node);
|
||||
write(" =>");
|
||||
}
|
||||
else {
|
||||
// When targeting ES6, emit arrow function natively in ES6
|
||||
if (shouldEmitAsArrowFunction(node)) {
|
||||
emitSignatureParametersForArrow(node);
|
||||
write(" =>");
|
||||
}
|
||||
else {
|
||||
emitSignatureParameters(node);
|
||||
}
|
||||
emitSignatureParameters(node);
|
||||
}
|
||||
|
||||
let isAsync = isAsyncFunctionLike(node);
|
||||
if (isAsync && languageVersion === ScriptTarget.ES6) {
|
||||
emitAsyncFunctionBodyForES6(node);
|
||||
}
|
||||
else {
|
||||
emitFunctionBody(node);
|
||||
}
|
||||
|
||||
|
||||
@ -1441,7 +1441,7 @@ module ts {
|
||||
serializeTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[];
|
||||
serializeParameterTypesOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): (string | string[])[];
|
||||
serializeReturnTypeOfNode(node: Node, getGeneratedNameForNode: (Node: Node) => string): string | string[];
|
||||
getPromiseConstructor(node: SignatureDeclaration): EntityName;
|
||||
getPromiseConstructor(node: SignatureDeclaration): EntityName | Expression;
|
||||
}
|
||||
|
||||
export const enum SymbolFlags {
|
||||
@ -1569,7 +1569,7 @@ module ts {
|
||||
SuperInstance = 0x00000100, // Instance 'super' reference
|
||||
SuperStatic = 0x00000200, // Static 'super' reference
|
||||
ContextChecked = 0x00000400, // Contextual types have been assigned
|
||||
PromiseCollision = 0x00000800, // Declaration collides with the global 'Promise'
|
||||
CaptureArguments = 0x00000800, // Lexical 'arguments' used in body (for async functions)
|
||||
|
||||
// Values for enum members have been computed, and any errors have been reported for them.
|
||||
EnumValuesComputed = 0x00001000,
|
||||
@ -1592,7 +1592,7 @@ module ts {
|
||||
assignmentChecks?: Map<boolean>; // Cache of assignment checks
|
||||
hasReportedStatementInAmbientContext?: boolean; // Cache boolean if we report statements in ambient context
|
||||
importOnRightSide?: Symbol; // for import declarations - import that appear on the right side
|
||||
promiseConstructor?: EntityName;
|
||||
promiseConstructor?: EntityName | Expression;
|
||||
}
|
||||
|
||||
export const enum TypeFlags {
|
||||
|
||||
@ -4,5 +4,5 @@ var foo = async (): Promise<void> => {
|
||||
};
|
||||
|
||||
//// [asyncArrowFunction1_es6.js]
|
||||
var foo = () => __awaiter(function *() {
|
||||
}.apply(this), Promise);
|
||||
var foo = () => __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
|
||||
@ -4,5 +4,5 @@ var foo = async (a = await): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction6_es6.js]
|
||||
var foo = (...arguments_1) => __awaiter(function *(a = await) {
|
||||
}.apply(this, arguments_1), Promise);
|
||||
var foo = (a = await) => __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
|
||||
@ -7,8 +7,8 @@ var bar = async (): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction7_es6.js]
|
||||
var bar = () => __awaiter(function *() {
|
||||
var bar = () => __awaiter(function* () {
|
||||
// 'await' here is an identifier, and not an await expression.
|
||||
var foo = (...arguments_1) => __awaiter(function *(a = await) {
|
||||
}.apply(this, arguments_1), Promise);
|
||||
}.apply(this), Promise);
|
||||
var foo = (a = await) => __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
}, this, void 0, Promise);
|
||||
|
||||
@ -5,6 +5,6 @@ var foo = async (): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction8_es6.js]
|
||||
var foo = () => __awaiter(function *() {
|
||||
var foo = () => __awaiter(function* () {
|
||||
var v = { [yield ]: foo };
|
||||
}.apply(this), Promise);
|
||||
}, this, void 0, Promise);
|
||||
|
||||
@ -3,5 +3,5 @@ var foo = async (a = await => await): Promise<void> => {
|
||||
}
|
||||
|
||||
//// [asyncArrowFunction9_es6.js]
|
||||
var foo = (...arguments_1) => __awaiter(function *(a = await => await) {
|
||||
}.apply(this, arguments_1), Promise);
|
||||
var foo = (a = await => await) => __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es6.ts(4,52): error TS2522: The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression.
|
||||
|
||||
|
||||
==== tests/cases/conformance/async/es6/asyncArrowFunction/asyncArrowFunctionCapturesArguments_es6.ts (1 errors) ====
|
||||
class C {
|
||||
method() {
|
||||
function other() {}
|
||||
var fn = async () => await other.apply(this, arguments);
|
||||
~~~~~~~~~
|
||||
!!! error TS2522: The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression.
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,6 @@ class C {
|
||||
class C {
|
||||
method() {
|
||||
function other() { }
|
||||
var fn = () => __awaiter(function *() { return yield other.apply(this, arguments); }.apply(this));
|
||||
var fn = () => __awaiter(function* (arguments) { return yield other.apply(this, arguments); }, this, arguments);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,6 +9,6 @@ class C {
|
||||
//// [asyncArrowFunctionCapturesThis_es6.js]
|
||||
class C {
|
||||
method() {
|
||||
var fn = () => __awaiter(function *() { return yield this; }.apply(this));
|
||||
var fn = () => __awaiter(function* () { return yield this; }, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ async function foo(a = await => await): Promise<void> {
|
||||
}
|
||||
|
||||
//// [asyncFunctionDeclaration10_es6.js]
|
||||
function foo() {
|
||||
return __awaiter(function *(a = await => await) {
|
||||
}.apply(this, arguments), Promise);
|
||||
function foo(a = await => await) {
|
||||
return __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -4,6 +4,6 @@ async function await(): Promise<void> {
|
||||
|
||||
//// [asyncFunctionDeclaration11_es6.js]
|
||||
function await() {
|
||||
return __awaiter(function *() {
|
||||
}.apply(this, arguments), Promise);
|
||||
return __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -7,8 +7,8 @@ async function foo(): Promise<void> {
|
||||
|
||||
//// [asyncFunctionDeclaration13_es6.js]
|
||||
function foo() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
// Legal to use 'await' in a type context.
|
||||
var v;
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ async function foo(): Promise<void> {
|
||||
|
||||
//// [asyncFunctionDeclaration14_es6.js]
|
||||
function foo() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
return;
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -4,6 +4,6 @@ async function foo(): Promise<void> {
|
||||
|
||||
//// [asyncFunctionDeclaration1_es6.js]
|
||||
function foo() {
|
||||
return __awaiter(function *() {
|
||||
}.apply(this, arguments), Promise);
|
||||
return __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -3,7 +3,7 @@ async function foo(a = await): Promise<void> {
|
||||
}
|
||||
|
||||
//// [asyncFunctionDeclaration6_es6.js]
|
||||
function foo() {
|
||||
return __awaiter(function *(a = await) {
|
||||
}.apply(this, arguments), Promise);
|
||||
function foo(a = await) {
|
||||
return __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -7,11 +7,11 @@ async function bar(): Promise<void> {
|
||||
|
||||
//// [asyncFunctionDeclaration7_es6.js]
|
||||
function bar() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
// 'await' here is an identifier, and not a yield expression.
|
||||
function foo() {
|
||||
return __awaiter(function *(a = await) {
|
||||
}.apply(this, arguments), Promise);
|
||||
function foo(a = await) {
|
||||
return __awaiter(function* () {
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ async function foo(): Promise<void> {
|
||||
|
||||
//// [asyncFunctionDeclaration9_es6.js]
|
||||
function foo() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
var v = { [yield ]: foo };
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -9,9 +9,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitBinaryExpression1_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = (yield p) || a;
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -9,9 +9,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitBinaryExpression2_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = (yield p) && a;
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -9,9 +9,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitBinaryExpression3_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = (yield p) + a;
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -9,9 +9,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitBinaryExpression4_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = yield p, a;
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -10,10 +10,10 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitBinaryExpression5_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var o;
|
||||
o.a = yield p;
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression1_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = fn(a, a, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression2_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = fn(yield p, a, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression3_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = fn(a, yield p, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression4_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = (yield pfn)(a, a, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression5_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = o.fn(a, a, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression6_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = o.fn(yield p, a, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression7_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = o.fn(a, yield p, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
@ -13,9 +13,9 @@ async function func(): Promise<void> {
|
||||
|
||||
//// [awaitCallExpression8_es6.js]
|
||||
function func() {
|
||||
return __awaiter(function *() {
|
||||
return __awaiter(function* () {
|
||||
"before";
|
||||
var b = (yield po).fn(a, a, a);
|
||||
"after";
|
||||
}.apply(this, arguments), Promise);
|
||||
}, this, void 0, Promise);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user