Better error messages in function calls.

Fixes #93.
This is an evolution of #220.
This commit is contained in:
Anders Hejlsberg
2014-07-24 17:00:03 -07:00
parent 64ab02ec43
commit a515b199b7
109 changed files with 641 additions and 571 deletions

View File

@@ -3634,9 +3634,8 @@ module ts {
(!node.typeArguments || signature.typeParameters && node.typeArguments.length === signature.typeParameters.length);
}
// The candidate list is in reverse order of declaration, except that groups of signatures with the same parent are
// kept in declaration order.
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[] {
// The candidate list orders groups in reverse, but within a group signatures are kept in declaration order
function collectCandidates(node: CallExpression, signatures: Signature[]): Signature[]{
var result: Signature[] = [];
var lastParent: Node;
var pos: number;
@@ -3733,15 +3732,22 @@ module ts {
return result;
}
function isApplicableSignature(node: CallExpression, signature: Signature, relation: Map<boolean>, excludeArgument: boolean[]) {
function checkApplicableSignature(node: CallExpression, signature: Signature, relation: Map<boolean>, excludeArgument: boolean[], reportErrors: boolean) {
if (node.arguments) {
for (var i = 0; i < node.arguments.length; i++) {
var arg = node.arguments[i];
var paramType = getTypeAtPosition(signature, i);
var argType = arg.kind === SyntaxKind.StringLiteral ?
// String literals get string literal types unless we're reporting errors
var argType = arg.kind === SyntaxKind.StringLiteral && !reportErrors ?
getStringLiteralType(<LiteralExpression>arg) :
checkExpression(arg, paramType, excludeArgument && excludeArgument[i] ? identityMapper : undefined);
if (!isTypeRelatedTo(argType, paramType, relation)) return false;
// Use argument expression as error location when reporting errors
var isValidArgument = checkTypeRelatedTo(argType, paramType, relation, reportErrors ? arg : undefined,
Diagnostics.Argument_type_0_is_not_assignable_to_parameter_type_1,
Diagnostics.Argument_type_0_is_not_assignable_to_parameter_type_1);
if (!isValidArgument) {
return false;
}
}
}
return true;
@@ -3773,7 +3779,9 @@ module ts {
inferTypeArguments(candidate, args, excludeArgument);
candidate = getSignatureInstantiation(candidate, typeArguments);
}
if (!isApplicableSignature(node, candidate, relation, excludeArgument)) break;
if (!checkApplicableSignature(node, candidate, relation, excludeArgument, /*reportErrors*/ false)) {
break;
}
var index = excludeArgument ? indexOf(excludeArgument, true) : -1;
if (index < 0) {
return getReturnTypeOfSignature(candidate);
@@ -3781,10 +3789,14 @@ module ts {
excludeArgument[index] = false;
}
}
if (relation === assignableRelation) break;
if (relation === assignableRelation) {
break;
}
relation = assignableRelation;
}
error(node, Diagnostics.Supplied_parameters_do_not_match_any_signature_of_call_target);
// No signatures were applicable. Now report errors based on the last applicable signature with
// no arguments excluded from assignability checks.
checkApplicableSignature(node, candidate, relation, undefined, /*reportErrors*/ true);
return checkErrorCall(node);
}

View File

@@ -190,6 +190,7 @@ module ts {
Specialized_overload_signature_is_not_assignable_to_any_non_specialized_signature: { code: 3033, category: DiagnosticCategory.Error, key: "Specialized overload signature is not assignable to any non-specialized signature." },
Duplicate_function_implementation: { code: 3034, category: DiagnosticCategory.Error, key: "Duplicate function implementation." },
Overload_signature_is_not_compatible_with_function_implementation: { code: 3035, category: DiagnosticCategory.Error, key: "Overload signature is not compatible with function implementation." },
Argument_type_0_is_not_assignable_to_parameter_type_1: { code: 3036, category: DiagnosticCategory.Error, key: "Argument type '{0}' is not assignable to parameter type '{1}'." },
Index_signature_is_missing_in_type_0: { code: 4003, category: DiagnosticCategory.Error, key: "Index signature is missing in type '{0}'." },
Index_signatures_are_incompatible_Colon: { code: 4004, category: DiagnosticCategory.Error, key: "Index signatures are incompatible:" },
Class_0_defines_instance_member_accessor_1_but_extended_class_2_defines_it_as_instance_member_function: { code: 4016, category: DiagnosticCategory.NoPrefix, key: "Class '{0}' defines instance member accessor '{1}', but extended class '{2}' defines it as instance member function." },

View File

@@ -753,7 +753,10 @@
"category": "Error",
"code": 3035
},
"Argument type '{0}' is not assignable to parameter type '{1}'.": {
"category": "Error",
"code": 3036
},
"Index signature is missing in type '{0}'.": {