@@ -824,7 +824,7 @@ namespace ts {
824
824
}
825
825
826
826
// Resolves a qualified name and any involved aliases
827
- function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags, location?: Node ): Symbol {
827
+ function resolveEntityName(name: EntityName | Expression, meaning: SymbolFlags): Symbol {
828
828
if (nodeIsMissing(name)) {
829
829
return undefined;
830
830
}
@@ -833,7 +833,7 @@ namespace ts {
833
833
if (name.kind === SyntaxKind.Identifier) {
834
834
let message = meaning === SymbolFlags.Namespace ? Diagnostics.Cannot_find_namespace_0 : Diagnostics.Cannot_find_name_0;
835
835
836
- symbol = resolveName(location || name, (<Identifier>name).text, meaning, message, <Identifier>name);
836
+ symbol = resolveName(name, (<Identifier>name).text, meaning, message, <Identifier>name);
837
837
if (!symbol) {
838
838
return undefined;
839
839
}
@@ -842,7 +842,7 @@ namespace ts {
842
842
let left = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).left : (<PropertyAccessExpression>name).expression;
843
843
let right = name.kind === SyntaxKind.QualifiedName ? (<QualifiedName>name).right : (<PropertyAccessExpression>name).name;
844
844
845
- let namespace = resolveEntityName(left, SymbolFlags.Namespace, location );
845
+ let namespace = resolveEntityName(left, SymbolFlags.Namespace);
846
846
if (!namespace || namespace === unknownSymbol || nodeIsMissing(right)) {
847
847
return undefined;
848
848
}
@@ -8839,7 +8839,6 @@ namespace ts {
8839
8839
}
8840
8840
8841
8841
if (produceDiagnostics) {
8842
- checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name);
8843
8842
checkCollisionWithArgumentsInGeneratedCode(node);
8844
8843
if (compilerOptions.noImplicitAny && !node.type) {
8845
8844
switch (node.kind) {
@@ -9632,18 +9631,18 @@ namespace ts {
9632
9631
* a `resolve` function as one of its arguments and results in an object with a
9633
9632
* callable `then` signature.
9634
9633
*/
9635
- function checkAsyncFunctionReturnType(node: SignatureDeclaration ): Type {
9634
+ function checkAsyncFunctionReturnType(node: FunctionLikeDeclaration ): Type {
9636
9635
let globalPromiseConstructorLikeType = getGlobalPromiseConstructorLikeType();
9637
9636
if (globalPromiseConstructorLikeType === emptyObjectType) {
9638
9637
// If we couldn't resolve the global PromiseConstructorLike type we cannot verify
9639
9638
// compatibility with __awaiter.
9640
9639
return unknownType;
9641
9640
}
9642
9641
9643
- // The return type of an async function will be the type of the instance. For this
9644
- // to be a type compatible with our async function emit, we must also check that
9645
- // the type of the declaration (e.g. the static side or "constructor" type of the
9646
- // promise) is a compatible `PromiseConstructorLike`.
9642
+ // As part of our emit for an async function, we will need to emit the entity name of
9643
+ // the return type annotation as an expression. To meet the necessary runtime semantics
9644
+ // for __awaiter, we must also check that the type of the declaration (e.g. the static
9645
+ // side or "constructor" of the promise type ) is compatible `PromiseConstructorLike`.
9647
9646
//
9648
9647
// An example might be (from lib.es6.d.ts):
9649
9648
//
@@ -9666,36 +9665,33 @@ namespace ts {
9666
9665
//
9667
9666
// When we get the type of the `Promise` symbol here, we get the type of the static
9668
9667
// side of the `Promise` class, which would be `{ new <T>(...): Promise<T> }`.
9669
- let returnType = getTypeFromTypeNode(node.type);
9670
- let entityName = getEntityNameFromTypeNode (node.type);
9671
- let resolvedName = entityName ? resolveEntityName(entityName, SymbolFlags.Value, node) : undefined ;
9672
- if (!resolvedName || !returnType.symbol ) {
9673
- error(node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type );
9674
- return unknownType;
9668
+
9669
+ let promiseType = getTypeFromTypeNode (node.type);
9670
+ let promiseConstructor = getMergedSymbol(promiseType.symbol) ;
9671
+ if (!promiseConstructor || !symbolIsValue(promiseConstructor) ) {
9672
+ error(node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type, typeToString(promiseType) );
9673
+ return unknownType
9675
9674
}
9676
-
9677
- if (getMergedSymbol(resolvedName) !== getMergedSymbol(returnType.symbol)) {
9678
- // If we were unable to resolve the return type as a value, report an error.
9679
- let identifier = getFirstIdentifier(entityName);
9680
- error(resolvedName.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
9681
- identifier.text,
9682
- identifier.text);
9675
+
9676
+ // Validate the promise constructor type.
9677
+ let promiseConstructorType = getTypeOfSymbol(promiseConstructor);
9678
+ if (!checkTypeAssignableTo(promiseConstructorType, globalPromiseConstructorLikeType, node, Diagnostics.Type_0_is_not_a_valid_async_function_return_type)) {
9683
9679
return unknownType;
9684
9680
}
9685
9681
9686
- // When we emit the async function, we need to ensure we emit any imports that might
9687
- // otherwise have been elided if the return type were only ever referenced in a type
9688
- // position. As such, we check the entity name as an expression.
9689
- let declaredType = checkExpression(entityName );
9690
-
9691
- if (!isTypeAssignableTo(declaredType, globalPromiseConstructorLikeType)) {
9692
- // If the declared type of the return type is not assignable to a PromiseConstructorLike, report an error.
9693
- error(node, ts.Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type );
9682
+ // Verify there is no local declaration that could collide with the promise constructor.
9683
+ let promiseName = getEntityNameFromTypeNode(node. type);
9684
+ let root = getFirstIdentifier(promiseName);
9685
+ let rootSymbol = getSymbol(node.locals, root.text, SymbolFlags.Value );
9686
+ if (rootSymbol) {
9687
+ error(rootSymbol.valueDeclaration, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions,
9688
+ root.text,
9689
+ getFullyQualifiedName(promiseConstructor) );
9694
9690
return unknownType;
9695
9691
}
9696
-
9692
+
9697
9693
// Get and return the awaited type of the return type.
9698
- return getAwaitedType(returnType , node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
9694
+ return getAwaitedType(promiseType , node, Diagnostics.An_async_function_or_method_must_have_a_valid_awaitable_return_type);
9699
9695
}
9700
9696
9701
9697
/** Check a decorator */
@@ -10093,22 +10089,6 @@ namespace ts {
10093
10089
}
10094
10090
}
10095
10091
}
10096
-
10097
- function checkCollisionWithAwaiterVariablesInGeneratedCode(node: Node, name: DeclarationName): void {
10098
- if (!name || name.kind !== SyntaxKind.Identifier || isTypeNode(name)) {
10099
- return;
10100
- }
10101
-
10102
- let identifier = <Identifier>name;
10103
- let container = getContainingFunction(name);
10104
- if (container && isAsyncFunctionLike(container) && node.kind !== SyntaxKind.Identifier) {
10105
- let promiseConstructorName = getEntityNameFromTypeNode(container.type);
10106
- let firstIdentifier = promiseConstructorName ? getFirstIdentifier(promiseConstructorName) : undefined;
10107
- if (firstIdentifier && firstIdentifier.text === identifier.text) {
10108
- error(node, Diagnostics.Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions, identifier.text, getTextOfNode(promiseConstructorName));
10109
- }
10110
- }
10111
- }
10112
10092
10113
10093
// Check that a parameter initializer contains no references to parameters declared to the right of itself
10114
10094
function checkParameterInitializer(node: VariableLikeDeclaration): void {
@@ -10954,7 +10934,6 @@ namespace ts {
10954
10934
checkTypeNameIsReserved(node.name, Diagnostics.Class_name_cannot_be_0);
10955
10935
checkCollisionWithCapturedThisVariable(node, node.name);
10956
10936
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
10957
- checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name);
10958
10937
}
10959
10938
checkTypeParameters(node.typeParameters);
10960
10939
checkExportsOnMergedDeclarations(node);
@@ -11398,7 +11377,6 @@ namespace ts {
11398
11377
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
11399
11378
checkCollisionWithCapturedThisVariable(node, node.name);
11400
11379
checkCollisionWithRequireExportsInGeneratedCode(node, node.name);
11401
- checkCollisionWithAwaiterVariablesInGeneratedCode(node, node.name);
11402
11380
checkExportsOnMergedDeclarations(node);
11403
11381
11404
11382
computeEnumMemberValues(node);
0 commit comments