From a31edfc3bdb10cd04e4d7831ecc826193f5c1da4 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Fri, 20 Apr 2012 19:08:29 +0400 Subject: [PATCH] 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 --- .../jet/lang/resolve/calls/CallResolver.java | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 990d6298b69..219f06d9156 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -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 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());