Read only interface extracted from OverloadResolutionResult

This commit is contained in:
Andrey Breslav
2011-12-14 14:06:44 +04:00
parent be0165f1e5
commit 7d3d5b4c88
7 changed files with 122 additions and 89 deletions
@@ -372,10 +372,10 @@ public class CallResolver {
};
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
OverloadResolutionResults<D> resultsForFirstNonemptyCandidateSet = null;
OverloadResolutionResultsImpl<D> resultsForFirstNonemptyCandidateSet = null;
for (ResolutionTask<D> task : prioritizedTasks) {
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace);
OverloadResolutionResults<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
OverloadResolutionResultsImpl<D> results = performResolution(temporaryTrace, scope, expectedType, task, tracing);
if (results.isSuccess()) {
temporaryTrace.commit();
@@ -407,7 +407,7 @@ public class CallResolver {
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@NotNull
private <D extends CallableDescriptor> OverloadResolutionResults<D> performResolution(
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> performResolution(
@NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetType expectedType,
@NotNull ResolutionTask<D> task, @NotNull TracingStrategy tracing
@@ -593,7 +593,7 @@ public class CallResolver {
}
}
OverloadResolutionResults<D> results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates);
OverloadResolutionResultsImpl<D> results = computeResultAndReportErrors(trace, tracing, successfulCandidates, failedCandidates);
if (!results.singleDescriptor()) {
checkTypesWithNoCallee(trace, scope, task.getCall());
}
@@ -740,7 +740,7 @@ public class CallResolver {
}
@NotNull
private <D extends CallableDescriptor> OverloadResolutionResults<D> computeResultAndReportErrors(
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> computeResultAndReportErrors(
BindingTrace trace,
TracingStrategy tracing,
Set<ResolvedCallImpl<D>> successfulCandidates,
@@ -748,7 +748,7 @@ public class CallResolver {
// TODO : maybe it's better to filter overrides out first, and only then look for the maximally specific
if (successfulCandidates.size() > 0) {
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(successfulCandidates, true);
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(successfulCandidates, true);
if (results.isAmbiguity()) {
// 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
@@ -772,15 +772,15 @@ public class CallResolver {
}
}
if (!thisLevel.isEmpty()) {
OverloadResolutionResults<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
OverloadResolutionResultsImpl<D> results = chooseAndReportMaximallySpecific(thisLevel, false);
if (results.isSuccess()) {
results.getResult().getTrace().commit();
return OverloadResolutionResults.singleFailedCandidate(results.getResult());
return OverloadResolutionResultsImpl.singleFailedCandidate(results.getResult());
}
tracing.noneApplicable(trace, results.getResults());
tracing.recordAmbiguity(trace, results.getResults());
return OverloadResolutionResults.manyFailedCandidates(results.getResults());
return OverloadResolutionResultsImpl.manyFailedCandidates(results.getResults());
}
}
assert false : "Should not be reachable, cause every status must belong to some level";
@@ -789,17 +789,17 @@ public class CallResolver {
if (noOverrides.size() != 1) {
tracing.noneApplicable(trace, noOverrides);
tracing.recordAmbiguity(trace, noOverrides);
return OverloadResolutionResults.manyFailedCandidates(noOverrides);
return OverloadResolutionResultsImpl.manyFailedCandidates(noOverrides);
}
failedCandidates = noOverrides;
}
ResolvedCallImpl<D> failed = failedCandidates.iterator().next();
failed.getTrace().commit();
return OverloadResolutionResults.singleFailedCandidate(failed);
return OverloadResolutionResultsImpl.singleFailedCandidate(failed);
}
else {
tracing.unresolvedReference(trace);
return OverloadResolutionResults.nameNotFound();
return OverloadResolutionResultsImpl.nameNotFound();
}
}
@@ -810,7 +810,7 @@ public class CallResolver {
return true;
}
private <D extends CallableDescriptor> OverloadResolutionResults<D> chooseAndReportMaximallySpecific(Set<ResolvedCallImpl<D>> candidates, boolean discriminateGenerics) {
private <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> chooseAndReportMaximallySpecific(Set<ResolvedCallImpl<D>> candidates, boolean discriminateGenerics) {
if (candidates.size() != 1) {
Set<ResolvedCallImpl<D>> cleanCandidates = Sets.newLinkedHashSet(candidates);
for (Iterator<ResolvedCallImpl<D>> iterator = cleanCandidates.iterator(); iterator.hasNext(); ) {
@@ -825,26 +825,26 @@ public class CallResolver {
}
ResolvedCallImpl<D> maximallySpecific = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, false);
if (maximallySpecific != null) {
return OverloadResolutionResults.success(maximallySpecific);
return OverloadResolutionResultsImpl.success(maximallySpecific);
}
if (discriminateGenerics) {
ResolvedCallImpl<D> maximallySpecificGenericsDiscriminated = overloadingConflictResolver.findMaximallySpecific(cleanCandidates, true);
if (maximallySpecificGenericsDiscriminated != null) {
return OverloadResolutionResults.success(maximallySpecificGenericsDiscriminated);
return OverloadResolutionResultsImpl.success(maximallySpecificGenericsDiscriminated);
}
}
Set<ResolvedCallImpl<D>> noOverrides = OverridingUtil.filterOverrides(candidates, MAP_TO_RESULT);
return OverloadResolutionResults.ambiguity(noOverrides);
return OverloadResolutionResultsImpl.ambiguity(noOverrides);
}
else {
ResolvedCallImpl<D> result = candidates.iterator().next();
TemporaryBindingTrace temporaryTrace = result.getTrace();
temporaryTrace.commit();
return OverloadResolutionResults.success(result);
return OverloadResolutionResultsImpl.success(result);
}
}
@@ -868,7 +868,7 @@ public class CallResolver {
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
public OverloadResolutionResultsImpl<FunctionDescriptor> resolveExactSignature(@NotNull JetScope scope, @NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
List<ResolvedCallImpl<FunctionDescriptor>> result = findCandidatesByExactSignature(scope, receiver, name, parameterTypes);
BindingTraceContext trace = new BindingTraceContext();
@@ -4,13 +4,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import java.util.Collection;
import java.util.Collections;
/**
* @author abreslav
*/
public class OverloadResolutionResults<D extends CallableDescriptor> {
public enum Code {
* @author abreslav
*/
public interface OverloadResolutionResults<D extends CallableDescriptor> {
enum Code {
SUCCESS(true),
NAME_NOT_FOUND(false),
SINGLE_CANDIDATE_ARGUMENT_MISMATCH(false),
@@ -26,69 +25,22 @@ public class OverloadResolutionResults<D extends CallableDescriptor> {
boolean isSuccess() {
return success;
}
}
public static <D extends CallableDescriptor> OverloadResolutionResults<D> success(@NotNull ResolvedCallImpl<D> descriptor) {
return new OverloadResolutionResults<D>(Code.SUCCESS, Collections.singleton(descriptor));
}
public static <D extends CallableDescriptor> OverloadResolutionResults<D> nameNotFound() {
return new OverloadResolutionResults<D>(Code.NAME_NOT_FOUND, Collections.<ResolvedCallImpl<D>>emptyList());
}
public static <D extends CallableDescriptor> OverloadResolutionResults<D> singleFailedCandidate(ResolvedCallImpl<D> candidate) {
return new OverloadResolutionResults<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
}
public static <D extends CallableDescriptor> OverloadResolutionResults<D> manyFailedCandidates(Collection<ResolvedCallImpl<D>> failedCandidates) {
return new OverloadResolutionResults<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
}
public static <D extends CallableDescriptor> OverloadResolutionResults<D> ambiguity(Collection<ResolvedCallImpl<D>> descriptors) {
return new OverloadResolutionResults<D>(Code.AMBIGUITY, descriptors);
}
private final Collection<ResolvedCallImpl<D>> results;
private final Code resultCode;
private OverloadResolutionResults(@NotNull Code resultCode, @NotNull Collection<ResolvedCallImpl<D>> results) {
this.results = results;
this.resultCode = resultCode;
}
@NotNull
public Collection<ResolvedCallImpl<D>> getResults() {
return results;
}
Collection<? extends ResolvedCall<? extends D>> getResults();
@NotNull
public ResolvedCallImpl<D> getResult() {
assert singleDescriptor();
return results.iterator().next();
}
ResolvedCall<? extends D> getResult();
@NotNull
public Code getResultCode() {
return resultCode;
}
Code getResultCode();
public boolean isSuccess() {
return resultCode.isSuccess();
}
boolean isSuccess();
public boolean singleDescriptor() {
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
}
boolean singleDescriptor();
public boolean isNothing() {
return resultCode == Code.NAME_NOT_FOUND;
}
boolean isNothing();
public boolean isAmbiguity() {
return resultCode == Code.AMBIGUITY;
}
//
// public OverloadResolutionResults<D> newContents(@NotNull Collection<D> functionDescriptors) {
// return new OverloadResolutionResults<D>(resultCode, functionDescriptors);
// }
boolean isAmbiguity();
}
@@ -0,0 +1,83 @@
package org.jetbrains.jet.lang.resolve.calls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import java.util.Collection;
import java.util.Collections;
/**
* @author abreslav
*/
public class OverloadResolutionResultsImpl<D extends CallableDescriptor> implements OverloadResolutionResults<D> {
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> success(@NotNull ResolvedCallImpl<D> descriptor) {
return new OverloadResolutionResultsImpl<D>(Code.SUCCESS, Collections.singleton(descriptor));
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> nameNotFound() {
return new OverloadResolutionResultsImpl<D>(Code.NAME_NOT_FOUND, Collections.<ResolvedCallImpl<D>>emptyList());
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> singleFailedCandidate(ResolvedCallImpl<D> candidate) {
return new OverloadResolutionResultsImpl<D>(Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH, Collections.singleton(candidate));
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> manyFailedCandidates(Collection<ResolvedCallImpl<D>> failedCandidates) {
return new OverloadResolutionResultsImpl<D>(Code.MANY_FAILED_CANDIDATES, failedCandidates);
}
public static <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> ambiguity(Collection<ResolvedCallImpl<D>> descriptors) {
return new OverloadResolutionResultsImpl<D>(Code.AMBIGUITY, descriptors);
}
private final Collection<ResolvedCallImpl<D>> results;
private final Code resultCode;
private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection<ResolvedCallImpl<D>> results) {
this.results = results;
this.resultCode = resultCode;
}
@Override
@NotNull
public Collection<ResolvedCallImpl<D>> getResults() {
return results;
}
@Override
@NotNull
public ResolvedCallImpl<D> getResult() {
assert singleDescriptor();
return results.iterator().next();
}
@Override
@NotNull
public Code getResultCode() {
return resultCode;
}
@Override
public boolean isSuccess() {
return resultCode.isSuccess();
}
@Override
public boolean singleDescriptor() {
return isSuccess() || resultCode == Code.SINGLE_CANDIDATE_ARGUMENT_MISMATCH;
}
@Override
public boolean isNothing() {
return resultCode == Code.NAME_NOT_FOUND;
}
@Override
public boolean isAmbiguity() {
return resultCode == Code.AMBIGUITY;
}
//
// public OverloadResolutionResultsImpl<D> newContents(@NotNull Collection<D> functionDescriptors) {
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
// }
}
@@ -15,7 +15,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.constants.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl;
@@ -727,7 +727,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
String name = "equals";
if (right != null) {
ExpressionReceiver receiver = ExpressionTypingUtils.safeGetExpressionReceiver(facade, left, context.replaceScope(context.scope));
OverloadResolutionResults<FunctionDescriptor> resolutionResults = context.resolveExactSignature(
OverloadResolutionResultsImpl<FunctionDescriptor> resolutionResults = context.resolveExactSignature(
receiver, "equals",
Collections.singletonList(JetStandardClasses.getNullableAnyType()));
if (resolutionResults.isSuccess()) {
@@ -10,10 +10,8 @@ import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.DescriptorUtils;
import org.jetbrains.jet.lang.resolve.calls.TaskPrioritizers;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
@@ -237,7 +235,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@Nullable
private JetType checkIterableConvention(@NotNull ExpressionReceiver loopRange, ExpressionTypingContext context) {
JetExpression loopRangeExpression = loopRange.getExpression();
OverloadResolutionResults<FunctionDescriptor> iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.<JetType>emptyList());
OverloadResolutionResultsImpl<FunctionDescriptor> iteratorResolutionResults = context.resolveExactSignature(loopRange, "iterator", Collections.<JetType>emptyList());
if (iteratorResolutionResults.isSuccess()) {
FunctionDescriptor iteratorFunction = iteratorResolutionResults.getResult().getResultingDescriptor();
@@ -259,7 +257,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
context.trace.record(LOOP_RANGE_HAS_NEXT, loopRange.getExpression(), hasNextFunctionSupported ? hasNextFunction : hasNextProperty);
}
OverloadResolutionResults<FunctionDescriptor> nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.<JetType>emptyList());
OverloadResolutionResultsImpl<FunctionDescriptor> nextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "next", Collections.<JetType>emptyList());
if (nextResolutionResults.isAmbiguity()) {
context.trace.report(NEXT_AMBIGUITY.on(loopRangeExpression));
} else if (nextResolutionResults.isNothing()) {
@@ -288,7 +286,7 @@ public class ControlStructureTypingVisitor extends ExpressionTypingVisitor {
@Nullable
private FunctionDescriptor checkHasNextFunctionSupport(@NotNull JetExpression loopRange, @NotNull JetType iteratorType, ExpressionTypingContext context) {
OverloadResolutionResults<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
OverloadResolutionResultsImpl<FunctionDescriptor> hasNextResolutionResults = context.resolveExactSignature(new TransientReceiver(iteratorType), "hasNext", Collections.<JetType>emptyList());
if (hasNextResolutionResults.isAmbiguity()) {
context.trace.report(HAS_NEXT_FUNCTION_AMBIGUITY.on(loopRange));
} else if (hasNextResolutionResults.isNothing()) {
@@ -12,7 +12,7 @@ import org.jetbrains.jet.lang.resolve.DescriptorResolver;
import org.jetbrains.jet.lang.resolve.TypeResolver;
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstantResolver;
@@ -196,7 +196,7 @@ import java.util.Map;
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
public OverloadResolutionResultsImpl<FunctionDescriptor> resolveExactSignature(@NotNull ReceiverDescriptor receiver, @NotNull String name, @NotNull List<JetType> parameterTypes) {
return getCallResolver().resolveExactSignature(scope, receiver, name, parameterTypes);
}
}
@@ -16,7 +16,7 @@ import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor;
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResults;
import org.jetbrains.jet.lang.resolve.calls.OverloadResolutionResultsImpl;
import org.jetbrains.jet.lang.resolve.calls.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
@@ -113,7 +113,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
// JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext());
CallResolver callResolver = new CallResolver(JetSemanticServices.createSemanticServices(getProject()), DataFlowInfo.EMPTY);
OverloadResolutionResults<FunctionDescriptor> functions = callResolver.resolveExactSignature(
OverloadResolutionResultsImpl<FunctionDescriptor> functions = callResolver.resolveExactSignature(
classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList);
for (ResolvedCallImpl<FunctionDescriptor> resolvedCall : functions.getResults()) {
List<ValueParameterDescriptor> unsubstitutedValueParameters = resolvedCall.getResultingDescriptor().getValueParameters();