Improved error reporting for candidates with wrong parameter count

This commit is contained in:
Stanislav Erokhin
2015-08-31 20:32:59 +03:00
parent 8ea6f36903
commit 5ded315cbb
23 changed files with 82 additions and 52 deletions
@@ -160,7 +160,7 @@ public class CandidateResolver(
val argumentMappingStatus = ValueArgumentsToParametersMapper.mapValueArgumentsToParameters(
call, tracing, candidateCall, Sets.newLinkedHashSet<ValueArgument>())
if (!argumentMappingStatus.isSuccess()) {
candidateCall.addStatus(OTHER_ERROR)
candidateCall.addStatus(ARGUMENTS_MAPPING_ERROR)
}
}
@@ -136,33 +136,36 @@ public class ResolutionResultsHandler {
}
}
if (!thisLevel.isEmpty()) {
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
if (results.isSingleResult()) {
results.getResultingCall().getTrace().moveAllMyDataTo(task.trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResultingCall());
if (severityLevel.contains(ARGUMENTS_MAPPING_ERROR)) {
return recordFailedInfo(task, thisLevel);
}
task.tracing.noneApplicable(task.trace, results.getResultingCalls());
task.tracing.recordAmbiguity(task.trace, results.getResultingCalls());
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResultingCalls());
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
return recordFailedInfo(task, results.getResultingCalls());
}
}
assert false : "Should not be reachable, cause every status must belong to some level";
Set<MutableResolvedCall<D>> noOverrides = OverrideResolver.filterOutOverridden(failedCandidates, MAP_TO_CANDIDATE);
if (noOverrides.size() != 1) {
task.tracing.noneApplicable(task.trace, noOverrides);
task.tracing.recordAmbiguity(task.trace, noOverrides);
return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides);
}
failedCandidates = noOverrides;
return recordFailedInfo(task, noOverrides);
}
MutableResolvedCall<D> failed = failedCandidates.iterator().next();
failed.getTrace().moveAllMyDataTo(task.trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
return recordFailedInfo(task, failedCandidates);
}
@NotNull
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> recordFailedInfo(
@NotNull ResolutionTask task,
@NotNull Collection<MutableResolvedCall<D>> candidates
) {
if (candidates.size() == 1) {
MutableResolvedCall<D> failed = candidates.iterator().next();
failed.getTrace().moveAllMyDataTo(task.trace);
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
}
task.tracing.noneApplicable(task.trace, candidates);
task.tracing.recordAmbiguity(task.trace, candidates);
return OverloadResolutionResultsImpl.manyFailedCandidates(candidates);
}
private static <D extends CallableDescriptor> boolean allIncomplete(@NotNull Collection<MutableResolvedCall<D>> results) {
@@ -31,6 +31,7 @@ public enum ResolutionStatus {
// 'a.foo()' shouldn't be resolved to package level non-extension 'fun foo()'
// candidates with such error are thrown away completely
RECEIVER_PRESENCE_ERROR,
ARGUMENTS_MAPPING_ERROR,
INCOMPLETE_TYPE_INFERENCE,
SUCCESS(true);
@@ -38,6 +39,7 @@ public enum ResolutionStatus {
public static final EnumSet<ResolutionStatus>[] SEVERITY_LEVELS = new EnumSet[] {
EnumSet.of(UNSAFE_CALL_ERROR), // weakest
EnumSet.of(OTHER_ERROR),
EnumSet.of(ARGUMENTS_MAPPING_ERROR),
EnumSet.of(RECEIVER_TYPE_ERROR),
EnumSet.of(RECEIVER_PRESENCE_ERROR), // most severe
};