Fix arity checking for partial overload resolution

This commit is contained in:
Jason Freeman
2014-09-26 13:51:13 -07:00
parent f2880ce5b7
commit ab3326f7b7
4 changed files with 56 additions and 23 deletions

View File

@@ -4331,25 +4331,32 @@ module ts {
}
function signatureHasCorrectArity(node: CallExpression, signature: Signature): boolean {
var args = node.arguments || emptyArray;
var isCorrect = args.length >= signature.minArgumentCount &&
(signature.hasRestParameter || args.length <= signature.parameters.length) &&
(!node.typeArguments || signature.typeParameters && node.typeArguments.length === signature.typeParameters.length);
// For error recovery, since we have parsed OmittedExpressions for any extra commas
// in the argument list, if we see any OmittedExpressions, just return true.
// The reason this is ok is because omitted expressions here are syntactically
// illegal, and will cause a parse error.
// Note: It may be worth keeping the upper bound check on arity, but removing
// the lower bound check if there are omitted expressions.
if (!isCorrect) {
// Technically this type assertion is not safe because args could be initialized to emptyArray
// above.
if ((<NodeArray<Node>>args).hasTrailingComma || forEach(args, arg => arg.kind === SyntaxKind.OmittedExpression)) {
return true;
}
if (!node.arguments) {
// This only happens when we have something of the form:
// new C
//
return signature.minArgumentCount === 0;
}
return isCorrect;
// For IDE scenarios, since we may have an incomplete call, we make two modifications
// to arity checking.
// 1. A trailing comma is tantamount to adding another argument
// 2. If the call is incomplete (no closing paren) allow fewer arguments than expected
var args = node.arguments;
var numberOfArgs = args.hasTrailingComma ? args.length + 1 : args.length;
var hasTooManyArguments = !signature.hasRestParameter && numberOfArgs > signature.parameters.length;
var hasRightNumberOfTypeArguments = !node.typeArguments ||
(signature.typeParameters && node.typeArguments.length === signature.typeParameters.length);
if (hasTooManyArguments || !hasRightNumberOfTypeArguments) {
return false;
}
// If we are missing the close paren, the call is incomplete, and we should skip
// the lower bound check.
var callIsIncomplete = args.end === node.end;
var hasEnoughArguments = numberOfArgs >= signature.minArgumentCount;
return callIsIncomplete || hasEnoughArguments;
}
// If type has a single call signature and no other members, return that signature. Otherwise, return undefined.