save explicitly 'INCOMPLETE_TYPE_INFERENCE' status
This commit is contained in:
+1
-12
@@ -27,9 +27,6 @@ import java.util.Collections;
|
||||
public class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallWithTrace<D> candidate) {
|
||||
if (candidate.hasUnknownTypeParameters()) {
|
||||
return incompleteTypeInference(candidate);
|
||||
}
|
||||
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(candidate));
|
||||
}
|
||||
|
||||
@@ -38,9 +35,6 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> singleFailedCandidate(ResolvedCallWithTrace<D> candidate) {
|
||||
if (candidate.getStatus() != ResolutionStatus.STRONG_ERROR && candidate.hasUnknownTypeParameters()) {
|
||||
return incompleteTypeInference(candidate);
|
||||
}
|
||||
return new OverloadResolutionResultsImpl<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
|
||||
}
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<ResolvedCallWithTrace<D>> failedCandidates) {
|
||||
@@ -48,11 +42,6 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
|
||||
}
|
||||
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallWithTrace<D>> candidates) {
|
||||
for (ResolvedCallWithTrace<D> candidate : candidates) {
|
||||
if (candidate.hasUnknownTypeParameters()) {
|
||||
return incompleteTypeInference(candidates);
|
||||
}
|
||||
}
|
||||
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, candidates);
|
||||
}
|
||||
|
||||
@@ -60,7 +49,7 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
|
||||
return new OverloadResolutionResultsImpl<D>(Code.INCOMPLETE_TYPE_INFERENCE, candidates);
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> candidate) {
|
||||
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> incompleteTypeInference(ResolvedCallWithTrace<D> candidate) {
|
||||
return incompleteTypeInference(Collections.singleton(candidate));
|
||||
}
|
||||
|
||||
|
||||
+24
-16
@@ -24,10 +24,7 @@ import org.jetbrains.jet.lang.resolve.OverridingUtil;
|
||||
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
|
||||
import org.jetbrains.jet.lang.resolve.calls.tasks.TracingStrategy;
|
||||
|
||||
import java.util.Collection;
|
||||
import java.util.EnumSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl.MAP_TO_CANDIDATE;
|
||||
import static org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl.MAP_TO_RESULT;
|
||||
@@ -73,28 +70,32 @@ public class ResolutionResultsHandler {
|
||||
) {
|
||||
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
|
||||
|
||||
if (successfulCandidates.size() > 0) {
|
||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(successfulCandidates, true);
|
||||
if (!successfulCandidates.isEmpty() || !incompleteCandidates.isEmpty()) {
|
||||
Set<ResolvedCallWithTrace<D>> successfulAndIncomplete = Sets.newLinkedHashSet();
|
||||
successfulAndIncomplete.addAll(successfulCandidates);
|
||||
successfulAndIncomplete.addAll(incompleteCandidates);
|
||||
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(successfulAndIncomplete, true);
|
||||
if (results.isSingleResult()) {
|
||||
results.getResultingCall().getTrace().moveAllMyDataTo(trace);
|
||||
ResolvedCallWithTrace<D> resultingCall = results.getResultingCall();
|
||||
resultingCall.getTrace().moveAllMyDataTo(trace);
|
||||
if (resultingCall.getStatus() == INCOMPLETE_TYPE_INFERENCE) {
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(resultingCall);
|
||||
}
|
||||
}
|
||||
if (results.isAmbiguity()) {
|
||||
tracing.recordAmbiguity(trace, results.getResultingCalls());
|
||||
if (allIncomplete(results.getResultingCalls())) {
|
||||
tracing.cannotCompleteResolve(trace, results.getResultingCalls());
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(results.getResultingCalls());
|
||||
}
|
||||
// This check is needed for the following case:
|
||||
// x.foo(unresolved) -- if there are multiple foo's, we'd report an ambiguity, and it does not make sense here
|
||||
if (allClean(results.getResultingCalls())) {
|
||||
tracing.ambiguity(trace, results.getResultingCalls());
|
||||
}
|
||||
tracing.recordAmbiguity(trace, results.getResultingCalls());
|
||||
}
|
||||
return results;
|
||||
}
|
||||
else if (!incompleteCandidates.isEmpty()) {
|
||||
assert incompleteCandidates.size() > 1 :
|
||||
"One incomplete candidate should have been chosen as maximally specific and completed earlier";
|
||||
tracing.cannotCompleteResolve(trace, incompleteCandidates);
|
||||
tracing.recordAmbiguity(trace, incompleteCandidates);
|
||||
return OverloadResolutionResultsImpl.incompleteTypeInference(incompleteCandidates);
|
||||
}
|
||||
else if (!failedCandidates.isEmpty()) {
|
||||
if (failedCandidates.size() != 1) {
|
||||
// This is needed when there are several overloads some of which are OK but for nullability of the receiver,
|
||||
@@ -142,13 +143,20 @@ public class ResolutionResultsHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private <D extends CallableDescriptor> boolean allClean(Collection<ResolvedCallWithTrace<D>> results) {
|
||||
private static <D extends CallableDescriptor> boolean allClean(@NotNull Collection<ResolvedCallWithTrace<D>> results) {
|
||||
for (ResolvedCallWithTrace<D> result : results) {
|
||||
if (result.isDirty()) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static <D extends CallableDescriptor> boolean allIncomplete(@NotNull Collection<ResolvedCallWithTrace<D>> results) {
|
||||
for (ResolvedCallWithTrace<D> result : results) {
|
||||
if (result.getStatus() != INCOMPLETE_TYPE_INFERENCE) return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(
|
||||
@NotNull Set<ResolvedCallWithTrace<D>> candidates,
|
||||
|
||||
+18
-3
@@ -49,11 +49,26 @@ public enum ResolutionStatus {
|
||||
}
|
||||
|
||||
public ResolutionStatus combine(ResolutionStatus other) {
|
||||
if (this == UNKNOWN_STATUS || this.isSuccess()) return other;
|
||||
if (!other.isSuccess() && this.getSeverityIndex() < other.getSeverityIndex()) return other;
|
||||
if (this == UNKNOWN_STATUS) return other;
|
||||
if (SUCCESS.among(this, other)) {
|
||||
return SUCCESS.chooseDifferent(this, other);
|
||||
}
|
||||
if (INCOMPLETE_TYPE_INFERENCE.among(this, other)) {
|
||||
return INCOMPLETE_TYPE_INFERENCE.chooseDifferent(this, other);
|
||||
}
|
||||
if (this.getSeverityIndex() < other.getSeverityIndex()) return other;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
private boolean among(ResolutionStatus first, ResolutionStatus second) {
|
||||
return this == first || this == second;
|
||||
}
|
||||
|
||||
private ResolutionStatus chooseDifferent(ResolutionStatus first, ResolutionStatus second) {
|
||||
assert among(first, second);
|
||||
return this == first ? second : first;
|
||||
}
|
||||
|
||||
private int getSeverityIndex() {
|
||||
if (severityIndex == -1) {
|
||||
for (int i = 0; i < SEVERITY_LEVELS.length; i++) {
|
||||
|
||||
Reference in New Issue
Block a user