KT-1835 cannot call a Java API which has a method from(String) and from(String...)

The problem was in the "more specific" relation, that didn't pay enough attention to varargs.
The correct behavior is in the spirit of JLS 15.12.2 (as of Java 5):
 * a fixed-arity function always wins over a variable-arity functions
 * if two vararg functions are compared, their parameters are checked for subtyping.
  In the latter case, the candidates may have different number of formal parameters, so we
  compare the matching parts and then check the rest against the vararg parameter.

 #KT-1835 Fixed
This commit is contained in:
Andrey Breslav
2012-04-20 19:08:29 +04:00
parent 45a0873afa
commit a31edfc3bd
@@ -391,31 +391,35 @@ public class CallResolver {
context.tracing.bindReference(context.trace, candidateCall);
if (ErrorUtils.isError(candidate)) {
candidateCall.setStatus(SUCCESS);
candidateCall.addStatus(SUCCESS);
checkTypesWithNoCallee(context.toBasic());
return;
}
if (!Visibilities.isVisible(candidate, context.scope.getContainingDeclaration())) {
candidateCall.setStatus(OTHER_ERROR);
candidateCall.addStatus(OTHER_ERROR);
context.tracing.invisibleMember(context.trace, candidate);
return;
}
boolean errorInArgumentMapping = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing, candidateCall);
if (errorInArgumentMapping) {
candidateCall.setStatus(OTHER_ERROR);
checkTypesWithNoCallee(context.toBasic());
return;
ValueArgumentsToParametersMapper.Status
argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(context.call, context.tracing,
candidateCall);
if (!argumentMappingStatus.isSuccess()) {
candidateCall.addStatus(OTHER_ERROR);
if (argumentMappingStatus == ValueArgumentsToParametersMapper.Status.ERROR) {
checkTypesWithNoCallee(context.toBasic());
return;
}
}
List<JetTypeProjection> jetTypeArguments = context.call.getTypeArguments();
if (jetTypeArguments.isEmpty()) {
if (!candidate.getTypeParameters().isEmpty()) {
candidateCall.setStatus(inferTypeArguments(context));
candidateCall.addStatus(inferTypeArguments(context));
}
else {
candidateCall.setStatus(checkAllValueArguments(context));
candidateCall.addStatus(checkAllValueArguments(context));
}
}
else {
@@ -451,10 +455,10 @@ public class CallResolver {
TypeParameterDescriptor typeParameterDescriptor = typeParameters.get(i);
candidateCall.recordTypeArgument(typeParameterDescriptor, typeArguments.get(i));
}
candidateCall.setStatus(checkAllValueArguments(context));
candidateCall.addStatus(checkAllValueArguments(context));
}
else {
candidateCall.setStatus(OTHER_ERROR);
candidateCall.addStatus(OTHER_ERROR);
context.tracing.wrongNumberOfTypeArguments(context.trace, expectedTypeArgumentCount);
}
}
@@ -466,7 +470,7 @@ public class CallResolver {
JetSuperExpression superExpression = TaskPrioritizer.getReceiverSuper(candidateCall.getReceiverArgument());
if (superExpression != null) {
context.trace.report(SUPER_IS_NOT_AN_EXPRESSION.on(superExpression, superExpression.getText()));
candidateCall.setStatus(OTHER_ERROR);
candidateCall.addStatus(OTHER_ERROR);
}
recordAutoCastIfNecessary(candidateCall.getReceiverArgument(), candidateCall.getTrace());