From d09c5c5e5e385f329d80be2036298db0db022e66 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Tue, 5 Feb 2013 19:16:46 +0400 Subject: [PATCH] save explicitly 'INCOMPLETE_TYPE_INFERENCE' status --- .../OverloadResolutionResultsImpl.java | 13 +----- .../results/ResolutionResultsHandler.java | 40 +++++++++++-------- .../calls/results/ResolutionStatus.java | 21 ++++++++-- 3 files changed, 43 insertions(+), 31 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java index 15c50ea7a96..50d73d3eede 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResultsImpl.java @@ -27,9 +27,6 @@ import java.util.Collections; public class OverloadResolutionResultsImpl implements OverloadResolutionResults { public static OverloadResolutionResultsImpl success(@NotNull ResolvedCallWithTrace candidate) { - if (candidate.hasUnknownTypeParameters()) { - return incompleteTypeInference(candidate); - } return new OverloadResolutionResultsImpl(Code.SUCCESS, Collections.singleton(candidate)); } @@ -38,9 +35,6 @@ public class OverloadResolutionResultsImpl impleme } public static OverloadResolutionResultsImpl singleFailedCandidate(ResolvedCallWithTrace candidate) { - if (candidate.getStatus() != ResolutionStatus.STRONG_ERROR && candidate.hasUnknownTypeParameters()) { - return incompleteTypeInference(candidate); - } return new OverloadResolutionResultsImpl(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate)); } public static OverloadResolutionResultsImpl manyFailedCandidates(Collection> failedCandidates) { @@ -48,11 +42,6 @@ public class OverloadResolutionResultsImpl impleme } public static OverloadResolutionResultsImpl ambiguity(Collection> candidates) { - for (ResolvedCallWithTrace candidate : candidates) { - if (candidate.hasUnknownTypeParameters()) { - return incompleteTypeInference(candidates); - } - } return new OverloadResolutionResultsImpl(Code.AMBIGUITY, candidates); } @@ -60,7 +49,7 @@ public class OverloadResolutionResultsImpl impleme return new OverloadResolutionResultsImpl(Code.INCOMPLETE_TYPE_INFERENCE, candidates); } - private static OverloadResolutionResultsImpl incompleteTypeInference(ResolvedCallWithTrace candidate) { + public static OverloadResolutionResultsImpl incompleteTypeInference(ResolvedCallWithTrace candidate) { return incompleteTypeInference(Collections.singleton(candidate)); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java index 0bbda0cd1c9..b7e5cef0c10 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionResultsHandler.java @@ -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 results = chooseAndReportMaximallySpecific(successfulCandidates, true); + if (!successfulCandidates.isEmpty() || !incompleteCandidates.isEmpty()) { + Set> successfulAndIncomplete = Sets.newLinkedHashSet(); + successfulAndIncomplete.addAll(successfulCandidates); + successfulAndIncomplete.addAll(incompleteCandidates); + OverloadResolutionResultsImpl results = chooseAndReportMaximallySpecific(successfulAndIncomplete, true); if (results.isSingleResult()) { - results.getResultingCall().getTrace().moveAllMyDataTo(trace); + ResolvedCallWithTrace 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 boolean allClean(Collection> results) { + private static boolean allClean(@NotNull Collection> results) { for (ResolvedCallWithTrace result : results) { if (result.isDirty()) return false; } return true; } + private static boolean allIncomplete(@NotNull Collection> results) { + for (ResolvedCallWithTrace result : results) { + if (result.getStatus() != INCOMPLETE_TYPE_INFERENCE) return false; + } + return true; + } + @NotNull private OverloadResolutionResultsImpl chooseAndReportMaximallySpecific( @NotNull Set> candidates, diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java index a72c71cbd5a..5d5ced260b9 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/ResolutionStatus.java @@ -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++) {