mirror of
https://github.com/microsoft/TypeScript.git
synced 2026-06-18 13:59:04 -05:00
Added additional es5 conformance tests, better emit for functions returning global promise, pass this to __generator
This commit is contained in:
@@ -148,6 +148,7 @@ namespace ts {
|
||||
let getGlobalESSymbolConstructorSymbol: () => Symbol;
|
||||
|
||||
let getGlobalPromiseConstructorSymbol: () => Symbol;
|
||||
let tryGetGlobalPromiseConstructorSymbol: () => Symbol;
|
||||
|
||||
let globalObjectType: ObjectType;
|
||||
let globalFunctionType: ObjectType;
|
||||
@@ -13922,7 +13923,7 @@ namespace ts {
|
||||
* @param returnType The return type of a FunctionLikeDeclaration
|
||||
* @param location The node on which to report the error.
|
||||
*/
|
||||
function checkCorrectPromiseType(returnType: Type, location: Node) {
|
||||
function checkCorrectPromiseType(returnType: Type, location: Node, diagnostic: DiagnosticMessage, typeName?: string) {
|
||||
if (returnType === unknownType) {
|
||||
// The return type already had some other error, so we ignore and return
|
||||
// the unknown type.
|
||||
@@ -13941,7 +13942,7 @@ namespace ts {
|
||||
|
||||
// The promise type was not a valid type reference to the global promise type, so we
|
||||
// report an error and return the unknown type.
|
||||
error(location, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
|
||||
error(location, diagnostic, typeName);
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
@@ -13961,7 +13962,7 @@ namespace ts {
|
||||
function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration): Type {
|
||||
if (languageVersion >= ScriptTarget.ES6) {
|
||||
const returnType = getTypeFromTypeNode(node.type);
|
||||
return checkCorrectPromiseType(returnType, node.type);
|
||||
return checkCorrectPromiseType(returnType, node.type, Diagnostics.The_return_type_of_an_async_function_or_method_must_be_the_global_Promise_T_type);
|
||||
}
|
||||
|
||||
const globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
|
||||
@@ -14007,11 +14008,11 @@ namespace ts {
|
||||
|
||||
const promiseConstructor = getNodeLinks(node.type).resolvedSymbol;
|
||||
if (!promiseConstructor || !symbolIsValue(promiseConstructor)) {
|
||||
// try to fall back to global promise type.
|
||||
const typeName = promiseConstructor
|
||||
? symbolToString(promiseConstructor)
|
||||
: typeToString(promiseType);
|
||||
error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName);
|
||||
return unknownType;
|
||||
return checkCorrectPromiseType(promiseType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeName);
|
||||
}
|
||||
|
||||
// If the Promise constructor, resolved locally, is an alias symbol we should mark it as referenced.
|
||||
@@ -14019,7 +14020,7 @@ namespace ts {
|
||||
|
||||
// Validate the promise constructor type.
|
||||
const promiseConstructorType = getTypeOfSymbol(promiseConstructor);
|
||||
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
|
||||
if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node.type, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
|
||||
return unknownType;
|
||||
}
|
||||
|
||||
@@ -17520,6 +17521,11 @@ namespace ts {
|
||||
function getTypeReferenceSerializationKind(typeName: EntityName, location?: Node): TypeReferenceSerializationKind {
|
||||
// Resolve the symbol as a value to ensure the type can be reached at runtime during emit.
|
||||
const valueSymbol = resolveEntityName(typeName, SymbolFlags.Value, /*ignoreErrors*/ true, /*dontResolveAlias*/ false, location);
|
||||
const globalPromiseSymbol = tryGetGlobalPromiseConstructorSymbol();
|
||||
if (globalPromiseSymbol && valueSymbol === globalPromiseSymbol) {
|
||||
return TypeReferenceSerializationKind.Promise;
|
||||
}
|
||||
|
||||
const constructorType = valueSymbol ? getTypeOfSymbol(valueSymbol) : undefined;
|
||||
if (constructorType && isConstructorType(constructorType)) {
|
||||
return TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue;
|
||||
@@ -17538,8 +17544,8 @@ namespace ts {
|
||||
else if (type.flags & TypeFlags.Any) {
|
||||
return TypeReferenceSerializationKind.ObjectType;
|
||||
}
|
||||
else if (isTypeOfKind(type, TypeFlags.Void)) {
|
||||
return TypeReferenceSerializationKind.VoidType;
|
||||
else if (isTypeOfKind(type, TypeFlags.Void | TypeFlags.Nullable | TypeFlags.Never)) {
|
||||
return TypeReferenceSerializationKind.VoidNullableOrNeverType;
|
||||
}
|
||||
else if (isTypeOfKind(type, TypeFlags.Boolean)) {
|
||||
return TypeReferenceSerializationKind.BooleanType;
|
||||
@@ -17837,6 +17843,7 @@ namespace ts {
|
||||
getGlobalPromiseLikeType = memoize(() => getGlobalType("PromiseLike", /*arity*/ 1));
|
||||
getInstantiatedGlobalPromiseLikeType = memoize(createInstantiatedPromiseLikeType);
|
||||
getGlobalPromiseConstructorSymbol = memoize(() => getGlobalValueSymbol("Promise"));
|
||||
tryGetGlobalPromiseConstructorSymbol = memoize(() => getGlobalSymbol("Promise", SymbolFlags.Value, /*diagnostic*/ undefined) && getGlobalPromiseConstructorSymbol());
|
||||
getGlobalPromiseConstructorLikeType = memoize(() => getGlobalType("PromiseConstructorLike"));
|
||||
getGlobalThenableType = memoize(createThenableType);
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
||||
};`;
|
||||
|
||||
const generatorHelper = `
|
||||
var __generator = (this && this.__generator) || function (body) {
|
||||
var __generator = (this && this.__generator) || function (thisArg, body) {
|
||||
var _ = { label: 0, sent: function() { if (sent[0] === 1) throw sent[1]; return sent[1]; }, trys: [], stack: [] }, sent, f;
|
||||
function step(op) {
|
||||
if (f) throw new TypeError("Generator is already executing.");
|
||||
@@ -97,7 +97,7 @@ var __generator = (this && this.__generator) || function (body) {
|
||||
_.trys.pop();
|
||||
continue;
|
||||
}
|
||||
op = body(_);
|
||||
op = body.call(thisArg, _);
|
||||
}
|
||||
catch (e) { op = [6, e]; }
|
||||
finally { f = 0, sent = void 0; }
|
||||
|
||||
@@ -2554,21 +2554,24 @@ namespace ts {
|
||||
return createCall(
|
||||
createHelperName(currentSourceFile.externalHelpersModuleName, "__generator"),
|
||||
/*typeArguments*/ undefined,
|
||||
[setNodeEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(state)],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
buildResult,
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ buildResult.length > 0
|
||||
)
|
||||
),
|
||||
NodeEmitFlags.ReuseTempVariableScope
|
||||
)]
|
||||
[
|
||||
createThis(),
|
||||
setNodeEmitFlags(
|
||||
createFunctionExpression(
|
||||
/*asteriskToken*/ undefined,
|
||||
/*name*/ undefined,
|
||||
/*typeParameters*/ undefined,
|
||||
[createParameter(state)],
|
||||
/*type*/ undefined,
|
||||
createBlock(
|
||||
buildResult,
|
||||
/*location*/ undefined,
|
||||
/*multiLine*/ buildResult.length > 0
|
||||
)
|
||||
),
|
||||
NodeEmitFlags.ReuseTempVariableScope
|
||||
)
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1774,7 +1774,7 @@ namespace ts {
|
||||
case TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue:
|
||||
return serializeEntityNameAsExpression(node.typeName, /*useFallback*/ false);
|
||||
|
||||
case TypeReferenceSerializationKind.VoidType:
|
||||
case TypeReferenceSerializationKind.VoidNullableOrNeverType:
|
||||
return createVoidZero();
|
||||
|
||||
case TypeReferenceSerializationKind.BooleanType:
|
||||
@@ -1797,6 +1797,9 @@ namespace ts {
|
||||
case TypeReferenceSerializationKind.TypeWithCallSignature:
|
||||
return createIdentifier("Function");
|
||||
|
||||
case TypeReferenceSerializationKind.Promise:
|
||||
return createIdentifier("Promise");
|
||||
|
||||
case TypeReferenceSerializationKind.ObjectType:
|
||||
default:
|
||||
return createIdentifier("Object");
|
||||
@@ -2221,8 +2224,21 @@ namespace ts {
|
||||
}
|
||||
}
|
||||
|
||||
function getPromiseConstructor(type: TypeNode) {
|
||||
const typeName = getEntityNameFromTypeNode(type);
|
||||
if (typeName && isEntityName(typeName)) {
|
||||
const serializationKind = resolver.getTypeReferenceSerializationKind(typeName);
|
||||
if (serializationKind === TypeReferenceSerializationKind.TypeWithConstructSignatureAndValue
|
||||
|| serializationKind === TypeReferenceSerializationKind.Unknown) {
|
||||
return typeName;
|
||||
}
|
||||
}
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function transformAsyncFunctionBody(node: FunctionLikeDeclaration): ConciseBody | FunctionBody {
|
||||
const promiseConstructor = languageVersion < ScriptTarget.ES6 ? getEntityNameFromTypeNode(node.type) : undefined;
|
||||
const promiseConstructor = languageVersion < ScriptTarget.ES6 ? getPromiseConstructor(node.type) : undefined;
|
||||
const isArrowFunction = node.kind === SyntaxKind.ArrowFunction;
|
||||
const hasLexicalArguments = (resolver.getNodeCheckFlags(node) & NodeCheckFlags.CaptureArguments) !== 0;
|
||||
|
||||
|
||||
@@ -2043,12 +2043,13 @@ namespace ts {
|
||||
// function that can be reached at runtime (e.g. a `class`
|
||||
// declaration or a `var` declaration for the static side
|
||||
// of a type, such as the global `Promise` type in lib.d.ts).
|
||||
VoidType, // The TypeReferenceNode resolves to a Void-like type.
|
||||
VoidNullableOrNeverType, // The TypeReferenceNode resolves to a Void-like, Nullable, or Never type.
|
||||
NumberLikeType, // The TypeReferenceNode resolves to a Number-like type.
|
||||
StringLikeType, // The TypeReferenceNode resolves to a String-like type.
|
||||
BooleanType, // The TypeReferenceNode resolves to a Boolean-like type.
|
||||
ArrayLikeType, // The TypeReferenceNode resolves to an Array-like type.
|
||||
ESSymbolType, // The TypeReferenceNode resolves to the ESSymbol type.
|
||||
Promise, // The TypeReferenceNode resolved to the global Promise constructor symbol.
|
||||
TypeWithCallSignature, // The TypeReferenceNode resolves to a Function type or a type
|
||||
// with call signatures.
|
||||
ObjectType, // The TypeReferenceNode resolves to any other type.
|
||||
|
||||
Reference in New Issue
Block a user