@@ -228,9 +228,9 @@ namespace ts {
228
228
isContextSensitive,
229
229
getFullyQualifiedName,
230
230
getResolvedSignature: (node, candidatesOutArray, agumentCount) =>
231
- getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ false ),
231
+ getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.Normal ),
232
232
getResolvedSignatureForSignatureHelp: (node, candidatesOutArray, agumentCount) =>
233
- getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, /*isForSignatureHelp*/ true ),
233
+ getResolvedSignatureWorker(node, candidatesOutArray, agumentCount, CheckMode.IsForSignatureHelp ),
234
234
getConstantValue: nodeIn => {
235
235
const node = getParseTreeNode(nodeIn, canHaveConstantValue);
236
236
return node ? getConstantValue(node) : undefined;
@@ -374,10 +374,10 @@ namespace ts {
374
374
getLocalTypeParametersOfClassOrInterfaceOrTypeAlias,
375
375
};
376
376
377
- function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, isForSignatureHelp: boolean ): Signature | undefined {
377
+ function getResolvedSignatureWorker(nodeIn: CallLikeExpression, candidatesOutArray: Signature[] | undefined, argumentCount: number | undefined, checkMode: CheckMode ): Signature | undefined {
378
378
const node = getParseTreeNode(nodeIn, isCallLikeExpression);
379
379
apparentArgumentCount = argumentCount;
380
- const res = node ? getResolvedSignature(node, candidatesOutArray, isForSignatureHelp ) : undefined;
380
+ const res = node ? getResolvedSignature(node, candidatesOutArray, checkMode ) : undefined;
381
381
apparentArgumentCount = undefined;
382
382
return res;
383
383
}
@@ -693,6 +693,7 @@ namespace ts {
693
693
Inferential = 1 << 1, // Inferential typing
694
694
SkipContextSensitive = 1 << 2, // Skip context sensitive function expressions
695
695
SkipGenericFunctions = 1 << 3, // Skip single signature generic functions
696
+ IsForSignatureHelp = 1 << 4, // Call resolution for purposes of signature help
696
697
}
697
698
698
699
const enum CallbackCheck {
@@ -20482,7 +20483,7 @@ namespace ts {
20482
20483
return createDiagnosticForNodeArray(getSourceFileOfNode(node), typeArguments, Diagnostics.Expected_0_type_arguments_but_got_1, belowArgCount === -Infinity ? aboveArgCount : belowArgCount, argCount);
20483
20484
}
20484
20485
20485
- function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean , fallbackError?: DiagnosticMessage): Signature {
20486
+ function resolveCall(node: CallLikeExpression, signatures: ReadonlyArray<Signature>, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode , fallbackError?: DiagnosticMessage): Signature {
20486
20487
const isTaggedTemplate = node.kind === SyntaxKind.TaggedTemplateExpression;
20487
20488
const isDecorator = node.kind === SyntaxKind.Decorator;
20488
20489
const isJsxOpeningOrSelfClosingElement = isJsxOpeningLikeElement(node);
@@ -20555,7 +20556,7 @@ namespace ts {
20555
20556
// If we are in signature help, a trailing comma indicates that we intend to provide another argument,
20556
20557
// so we will only accept overloads with arity at least 1 higher than the current number of provided arguments.
20557
20558
const signatureHelpTrailingComma =
20558
- isForSignatureHelp && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
20559
+ !!(checkMode & CheckMode.IsForSignatureHelp) && node.kind === SyntaxKind.CallExpression && node.arguments.hasTrailingComma;
20559
20560
20560
20561
// Section 4.12.1:
20561
20562
// if the candidate list contains one or more signatures for which the type of each argument
@@ -20837,7 +20838,7 @@ namespace ts {
20837
20838
return maxParamsIndex;
20838
20839
}
20839
20840
20840
- function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean ): Signature {
20841
+ function resolveCallExpression(node: CallExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode ): Signature {
20841
20842
if (node.expression.kind === SyntaxKind.SuperKeyword) {
20842
20843
const superType = checkSuperExpression(node.expression);
20843
20844
if (isTypeAny(superType)) {
@@ -20852,7 +20853,7 @@ namespace ts {
20852
20853
const baseTypeNode = getEffectiveBaseTypeNode(getContainingClass(node)!);
20853
20854
if (baseTypeNode) {
20854
20855
const baseConstructors = getInstantiatedConstructorsForTypeArguments(superType, baseTypeNode.typeArguments, baseTypeNode);
20855
- return resolveCall(node, baseConstructors, candidatesOutArray, isForSignatureHelp );
20856
+ return resolveCall(node, baseConstructors, candidatesOutArray, checkMode );
20856
20857
}
20857
20858
}
20858
20859
return resolveUntypedCall(node);
@@ -20912,12 +20913,22 @@ namespace ts {
20912
20913
}
20913
20914
return resolveErrorCall(node);
20914
20915
}
20916
+ // If we are skipping generic functions (i.e. this call is an argument to another call for which context
20917
+ // sensitive arguments are being deferred) and every call signature is generic and returns a function type,
20918
+ // we return resolvingSignature here. This result will be propagated out and turned into anyFunctionType.
20919
+ if (checkMode & CheckMode.SkipGenericFunctions && callSignatures.every(isGenericFunctionReturningFunction)) {
20920
+ return resolvingSignature;
20921
+ }
20915
20922
// If the function is explicitly marked with `@class`, then it must be constructed.
20916
20923
if (callSignatures.some(sig => isInJSFile(sig.declaration) && !!getJSDocClassTag(sig.declaration!))) {
20917
20924
error(node, Diagnostics.Value_of_type_0_is_not_callable_Did_you_mean_to_include_new, typeToString(funcType));
20918
20925
return resolveErrorCall(node);
20919
20926
}
20920
- return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp);
20927
+ return resolveCall(node, callSignatures, candidatesOutArray, checkMode);
20928
+ }
20929
+
20930
+ function isGenericFunctionReturningFunction(signature: Signature) {
20931
+ return !!(signature.typeParameters && getSingleCallSignature(getReturnTypeOfSignature(signature)));
20921
20932
}
20922
20933
20923
20934
/**
@@ -20931,7 +20942,7 @@ namespace ts {
20931
20942
!numCallSignatures && !numConstructSignatures && !(apparentFuncType.flags & (TypeFlags.Union | TypeFlags.Never)) && isTypeAssignableTo(funcType, globalFunctionType);
20932
20943
}
20933
20944
20934
- function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean ): Signature {
20945
+ function resolveNewExpression(node: NewExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode ): Signature {
20935
20946
if (node.arguments && languageVersion < ScriptTarget.ES5) {
20936
20947
const spreadIndex = getSpreadArgumentIndex(node.arguments);
20937
20948
if (spreadIndex >= 0) {
@@ -20984,7 +20995,7 @@ namespace ts {
20984
20995
return resolveErrorCall(node);
20985
20996
}
20986
20997
20987
- return resolveCall(node, constructSignatures, candidatesOutArray, isForSignatureHelp );
20998
+ return resolveCall(node, constructSignatures, candidatesOutArray, checkMode );
20988
20999
}
20989
21000
20990
21001
// If expressionType's apparent type is an object type with no construct signatures but
@@ -20993,7 +21004,7 @@ namespace ts {
20993
21004
// operation is Any. It is an error to have a Void this type.
20994
21005
const callSignatures = getSignaturesOfType(expressionType, SignatureKind.Call);
20995
21006
if (callSignatures.length) {
20996
- const signature = resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp );
21007
+ const signature = resolveCall(node, callSignatures, candidatesOutArray, checkMode );
20997
21008
if (!noImplicitAny) {
20998
21009
if (signature.declaration && !isJSConstructor(signature.declaration) && getReturnTypeOfSignature(signature) !== voidType) {
20999
21010
error(node, Diagnostics.Only_a_void_function_can_be_called_with_the_new_keyword);
@@ -21103,7 +21114,7 @@ namespace ts {
21103
21114
}
21104
21115
}
21105
21116
21106
- function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean ): Signature {
21117
+ function resolveTaggedTemplateExpression(node: TaggedTemplateExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode ): Signature {
21107
21118
const tagType = checkExpression(node.tag);
21108
21119
const apparentType = getApparentType(tagType);
21109
21120
@@ -21124,7 +21135,7 @@ namespace ts {
21124
21135
return resolveErrorCall(node);
21125
21136
}
21126
21137
21127
- return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp );
21138
+ return resolveCall(node, callSignatures, candidatesOutArray, checkMode );
21128
21139
}
21129
21140
21130
21141
/**
@@ -21155,7 +21166,7 @@ namespace ts {
21155
21166
/**
21156
21167
* Resolves a decorator as if it were a call expression.
21157
21168
*/
21158
- function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean ): Signature {
21169
+ function resolveDecorator(node: Decorator, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode ): Signature {
21159
21170
const funcType = checkExpression(node.expression);
21160
21171
const apparentType = getApparentType(funcType);
21161
21172
if (apparentType === errorType) {
@@ -21184,7 +21195,7 @@ namespace ts {
21184
21195
return resolveErrorCall(node);
21185
21196
}
21186
21197
21187
- return resolveCall(node, callSignatures, candidatesOutArray, isForSignatureHelp , headMessage);
21198
+ return resolveCall(node, callSignatures, candidatesOutArray, checkMode , headMessage);
21188
21199
}
21189
21200
21190
21201
function createSignatureForJSXIntrinsic(node: JsxOpeningLikeElement, result: Type): Signature {
@@ -21213,7 +21224,7 @@ namespace ts {
21213
21224
);
21214
21225
}
21215
21226
21216
- function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean ): Signature {
21227
+ function resolveJsxOpeningLikeElement(node: JsxOpeningLikeElement, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode ): Signature {
21217
21228
if (isJsxIntrinsicIdentifier(node.tagName)) {
21218
21229
const result = getIntrinsicAttributesTypeFromJsxOpeningLikeElement(node);
21219
21230
const fakeSignature = createSignatureForJSXIntrinsic(node, result);
@@ -21237,7 +21248,7 @@ namespace ts {
21237
21248
return resolveErrorCall(node);
21238
21249
}
21239
21250
21240
- return resolveCall(node, signatures, candidatesOutArray, isForSignatureHelp );
21251
+ return resolveCall(node, signatures, candidatesOutArray, checkMode );
21241
21252
}
21242
21253
21243
21254
/**
@@ -21252,19 +21263,19 @@ namespace ts {
21252
21263
signature.parameters.length < getDecoratorArgumentCount(decorator, signature));
21253
21264
}
21254
21265
21255
- function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, isForSignatureHelp: boolean ): Signature {
21266
+ function resolveSignature(node: CallLikeExpression, candidatesOutArray: Signature[] | undefined, checkMode: CheckMode ): Signature {
21256
21267
switch (node.kind) {
21257
21268
case SyntaxKind.CallExpression:
21258
- return resolveCallExpression(node, candidatesOutArray, isForSignatureHelp );
21269
+ return resolveCallExpression(node, candidatesOutArray, checkMode );
21259
21270
case SyntaxKind.NewExpression:
21260
- return resolveNewExpression(node, candidatesOutArray, isForSignatureHelp );
21271
+ return resolveNewExpression(node, candidatesOutArray, checkMode );
21261
21272
case SyntaxKind.TaggedTemplateExpression:
21262
- return resolveTaggedTemplateExpression(node, candidatesOutArray, isForSignatureHelp );
21273
+ return resolveTaggedTemplateExpression(node, candidatesOutArray, checkMode );
21263
21274
case SyntaxKind.Decorator:
21264
- return resolveDecorator(node, candidatesOutArray, isForSignatureHelp );
21275
+ return resolveDecorator(node, candidatesOutArray, checkMode );
21265
21276
case SyntaxKind.JsxOpeningElement:
21266
21277
case SyntaxKind.JsxSelfClosingElement:
21267
- return resolveJsxOpeningLikeElement(node, candidatesOutArray, isForSignatureHelp );
21278
+ return resolveJsxOpeningLikeElement(node, candidatesOutArray, checkMode );
21268
21279
}
21269
21280
throw Debug.assertNever(node, "Branch in 'resolveSignature' should be unreachable.");
21270
21281
}
@@ -21276,7 +21287,7 @@ namespace ts {
21276
21287
* the function will fill it up with appropriate candidate signatures
21277
21288
* @return a signature of the call-like expression or undefined if one can't be found
21278
21289
*/
21279
- function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, isForSignatureHelp = false ): Signature {
21290
+ function getResolvedSignature(node: CallLikeExpression, candidatesOutArray?: Signature[] | undefined, checkMode?: CheckMode ): Signature {
21280
21291
const links = getNodeLinks(node);
21281
21292
// If getResolvedSignature has already been called, we will have cached the resolvedSignature.
21282
21293
// However, it is possible that either candidatesOutArray was not passed in the first time,
@@ -21287,11 +21298,15 @@ namespace ts {
21287
21298
return cached;
21288
21299
}
21289
21300
links.resolvedSignature = resolvingSignature;
21290
- const result = resolveSignature(node, candidatesOutArray, isForSignatureHelp);
21291
- // If signature resolution originated in control flow type analysis (for example to compute the
21292
- // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
21293
- // types from the control flow analysis.
21294
- links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
21301
+ const result = resolveSignature(node, candidatesOutArray, checkMode || CheckMode.Normal);
21302
+ // When CheckMode.SkipGenericFunctions is set we use resolvingSignature to indicate that call
21303
+ // resolution should be deferred.
21304
+ if (result !== resolvingSignature) {
21305
+ // If signature resolution originated in control flow type analysis (for example to compute the
21306
+ // assigned type in a flow assignment) we don't cache the result as it may be based on temporary
21307
+ // types from the control flow analysis.
21308
+ links.resolvedSignature = flowLoopStart === flowLoopCount ? result : cached;
21309
+ }
21295
21310
return result;
21296
21311
}
21297
21312
@@ -21375,10 +21390,15 @@ namespace ts {
21375
21390
* @param node The call/new expression to be checked.
21376
21391
* @returns On success, the expression's signature's return type. On failure, anyType.
21377
21392
*/
21378
- function checkCallExpression(node: CallExpression | NewExpression): Type {
21393
+ function checkCallExpression(node: CallExpression | NewExpression, checkMode?: CheckMode ): Type {
21379
21394
if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments);
21380
21395
21381
- const signature = getResolvedSignature(node);
21396
+ const signature = getResolvedSignature(node, /*candidatesOutArray*/ undefined, checkMode);
21397
+ if (signature === resolvingSignature) {
21398
+ // CheckMode.SkipGenericFunctions is enabled and this is a call to a generic function that
21399
+ // returns a function type. We defer checking and return anyFunctionType.
21400
+ return anyFunctionType;
21401
+ }
21382
21402
21383
21403
if (node.expression.kind === SyntaxKind.SuperKeyword) {
21384
21404
return voidType;
@@ -23505,7 +23525,7 @@ namespace ts {
23505
23525
}
23506
23526
/* falls through */
23507
23527
case SyntaxKind.NewExpression:
23508
- return checkCallExpression(<CallExpression>node);
23528
+ return checkCallExpression(<CallExpression>node, checkMode );
23509
23529
case SyntaxKind.TaggedTemplateExpression:
23510
23530
return checkTaggedTemplateExpression(<TaggedTemplateExpression>node);
23511
23531
case SyntaxKind.ParenthesizedExpression:
0 commit comments