diff --git a/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index ca71c36983e..98923827d9d 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -215,10 +215,10 @@ public class CallResolver { }; for (ResolutionTask task : prioritizedTasks) { TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); - Descriptor descriptor = performResolution(temporaryTrace, scope, expectedType, task, tracing); - if (descriptor != null) { + OverloadResolutionResult result = performResolution(temporaryTrace, scope, expectedType, task, tracing); + if (result.isSuccess()) { temporaryTrace.commit(); - return descriptor; + return result.getDescriptor(); } if (traceForFirstNonemptyCandidateSet == null && !task.getCandidates().isEmpty()) { traceForFirstNonemptyCandidateSet = temporaryTrace; @@ -235,8 +235,8 @@ public class CallResolver { ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - @Nullable - private Descriptor performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing) { + @NotNull + private OverloadResolutionResult performResolution(@NotNull BindingTrace trace, @NotNull JetScope scope, @NotNull JetType expectedType, @NotNull ResolutionTask task, @NotNull TracingStrategy tracing) { Map successfulCandidates = Maps.newLinkedHashMap(); Set failedCandidates = Sets.newLinkedHashSet(); Set dirtyCandidates = Sets.newLinkedHashSet(); @@ -369,8 +369,8 @@ public class CallResolver { } } - Descriptor resultingDescriptor = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates, dirtyCandidates, traces); - if (resultingDescriptor == null) { + OverloadResolutionResult result = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates, dirtyCandidates, traces); + if (!result.singleDescriptor()) { for (ValueArgument valueArgument : task.getValueArguments()) { JetExpression argumentExpression = valueArgument.getArgumentExpression(); if (argumentExpression != null) { @@ -386,7 +386,7 @@ public class CallResolver { new TypeResolver(semanticServices, trace, true).resolveType(scope, typeProjection.getTypeReference()); } } - return resultingDescriptor; + return result; } private Function createMapFunction(Descriptor substitutedFunctionDescriptor) { @@ -433,8 +433,8 @@ public class CallResolver { return true; } - @Nullable - private Descriptor computeResultAndReportErrors(BindingTrace trace, TracingStrategy tracing, Map successfulCandidates, Set failedCandidates, Set dirtyCandidates, Map traces) { + @NotNull + private OverloadResolutionResult computeResultAndReportErrors(BindingTrace trace, TracingStrategy tracing, Map successfulCandidates, Set failedCandidates, Set dirtyCandidates, Map traces) { if (successfulCandidates.size() > 0) { if (successfulCandidates.size() == 1) { Map.Entry entry = successfulCandidates.entrySet().iterator().next(); @@ -443,7 +443,7 @@ public class CallResolver { TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor); temporaryTrace.commit(); - return result; + return OverloadResolutionResult.success(result); } else { Map cleanCandidates = Maps.newLinkedHashMap(successfulCandidates); @@ -453,12 +453,12 @@ public class CallResolver { } Descriptor maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, traces, false); if (maximallySpecific != null) { - return maximallySpecific; + return OverloadResolutionResult.success(maximallySpecific); } Descriptor maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, traces, true); if (maximallySpecificGenericsDiscriminated != null) { - return maximallySpecificGenericsDiscriminated; + return OverloadResolutionResult.success(maximallySpecificGenericsDiscriminated); } if (dirtyCandidates.isEmpty()) { @@ -469,6 +469,7 @@ public class CallResolver { tracing.reportOverallResolutionError(trace, "Overload resolution ambiguity: " + stringBuilder); } + return OverloadResolutionResult.ambiguity(successfulCandidates.keySet()); } } else if (!failedCandidates.isEmpty()) { @@ -476,7 +477,7 @@ public class CallResolver { Descriptor functionDescriptor = failedCandidates.iterator().next(); TemporaryBindingTrace temporaryTrace = traces.get(functionDescriptor); temporaryTrace.commit(); - return failedCandidates.iterator().next(); + return OverloadResolutionResult.singleFailedCandidate(failedCandidates.iterator().next()); } else { StringBuilder stringBuilder = new StringBuilder(); @@ -485,15 +486,13 @@ public class CallResolver { } tracing.reportOverallResolutionError(trace, "None of the following functions can be called with the arguments supplied: " + stringBuilder); + return OverloadResolutionResult.manyFailedCandidates(failedCandidates); } } else { tracing.reportUnresolvedReference(trace); + return OverloadResolutionResult.nameNotFound(); } - - - - return null; } private boolean checkValueArgumentTypes(JetScope scope, JetTypeInferrer.Services temporaryServices, Map argumentsToParameters, Flag dirty, Function parameterMap) { diff --git a/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java b/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java index 9ca7641757f..799d001616b 100644 --- a/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java +++ b/idea/src/org/jetbrains/jet/lang/resolve/calls/OverloadResolutionResult.java @@ -4,6 +4,7 @@ import org.jetbrains.annotations.NotNull; import java.util.Collection; import java.util.Collections; +import java.util.Set; /** * @author abreslav @@ -12,8 +13,9 @@ public class OverloadResolutionResult { public enum Code { SUCCESS(true), NAME_NOT_FOUND(false), - SINGLE_FUNCTION_ARGUMENT_MISMATCH(false), - AMBIGUITY(false); + SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false), + AMBIGUITY(false), + MANY_FAILED_CANDIDATES(false); private final boolean success; @@ -27,19 +29,23 @@ public class OverloadResolutionResult { } - public static OverloadResolutionResult success(@NotNull D functionDescriptor) { - return new OverloadResolutionResult(Code.SUCCESS, Collections.singleton(functionDescriptor)); + public static OverloadResolutionResult success(@NotNull D descriptor) { + return new OverloadResolutionResult(Code.SUCCESS, Collections.singleton(descriptor)); } public static OverloadResolutionResult nameNotFound() { return new OverloadResolutionResult(Code.NAME_NOT_FOUND, Collections.emptyList()); } - public static OverloadResolutionResult singleFunctionArgumentMismatch(D functionDescriptor) { - return new OverloadResolutionResult(Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH, Collections.singleton(functionDescriptor)); + + public static OverloadResolutionResult singleFailedCandidate(D candidate) { + return new OverloadResolutionResult(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate)); + } + public static OverloadResolutionResult manyFailedCandidates(Set failedCandidates) { + return new OverloadResolutionResult(Code.MANY_FAILED_CANDIDATES, failedCandidates); } - public static OverloadResolutionResult ambiguity(Collection functionDescriptors) { - return new OverloadResolutionResult(Code.AMBIGUITY, functionDescriptors); + public static OverloadResolutionResult ambiguity(Collection descriptors) { + return new OverloadResolutionResult(Code.AMBIGUITY, descriptors); } private final Collection descriptors; @@ -73,7 +79,7 @@ public class OverloadResolutionResult { } public boolean singleDescriptor() { - return isSuccess() || resultCode == Code.SINGLE_FUNCTION_ARGUMENT_MISMATCH; + return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH; } public boolean isNothing() {