Collect all resolved candidate calls if required

This commit is contained in:
Svetlana Isakova
2014-03-20 13:56:16 +04:00
committed by Andrey Breslav
parent e6a71563ba
commit 77880f667a
5 changed files with 58 additions and 22 deletions
@@ -28,6 +28,7 @@ import org.jetbrains.jet.lang.resolve.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.calls.context.*;
import org.jetbrains.jet.lang.resolve.calls.model.MutableDataFlowInfoForArguments;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallImpl;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
import org.jetbrains.jet.lang.resolve.calls.results.OverloadResolutionResults;
@@ -53,7 +54,8 @@ import java.util.Collections;
import java.util.List;
import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.NOT_A_CLASS;
import static org.jetbrains.jet.lang.diagnostics.Errors.NO_CONSTRUCTOR;
import static org.jetbrains.jet.lang.resolve.BindingContext.NON_DEFAULT_EXPRESSION_DATA_FLOW;
import static org.jetbrains.jet.lang.resolve.BindingContext.RESOLUTION_SCOPE;
import static org.jetbrains.jet.lang.resolve.calls.CallResolverUtil.ResolveArgumentsMode.RESOLVE_FUNCTION_ARGUMENTS;
@@ -495,21 +497,29 @@ public class CallResolver {
if (context.checkArguments == CheckValueArgumentsMode.ENABLED) {
argumentTypeResolver.analyzeArgumentsAndRecordTypes(context);
}
Collection<ResolvedCall<F>> allCandidates = Lists.newArrayList();
OverloadResolutionResultsImpl<F> successfulResults = null;
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null;
for (ResolutionTask<D, F> task : prioritizedTasks) {
if (successfulResults != null && !context.collectAllCandidates) continue;
TemporaryBindingTrace taskTrace =
TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.call.getCalleeExpression());
OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments(
task.replaceBindingTrace(taskTrace), callTransformer);
allCandidates.addAll(task.getResolvedCalls());
if (successfulResults != null) continue;
if (results.isSuccess() || results.isAmbiguity()) {
taskTrace.commit();
return results;
successfulResults = results;
}
if (results.getResultCode() == INCOMPLETE_TYPE_INFERENCE) {
results.setTrace(taskTrace);
return results;
successfulResults = results;
}
boolean updateResults = traceForFirstNonemptyCandidateSet == null
|| (resultsForFirstNonemptyCandidateSet.getResultCode() == CANDIDATES_WITH_WRONG_RECEIVER
@@ -519,13 +529,21 @@ public class CallResolver {
resultsForFirstNonemptyCandidateSet = results;
}
}
if (traceForFirstNonemptyCandidateSet == null) {
OverloadResolutionResultsImpl<F> results;
if (successfulResults != null) {
results = successfulResults;
}
else if (traceForFirstNonemptyCandidateSet == null) {
tracing.unresolvedReference(context.trace);
argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS);
return OverloadResolutionResultsImpl.<F>nameNotFound();
results = OverloadResolutionResultsImpl.<F>nameNotFound();
}
traceForFirstNonemptyCandidateSet.commit();
return resultsForFirstNonemptyCandidateSet;
else {
traceForFirstNonemptyCandidateSet.commit();
results = resultsForFirstNonemptyCandidateSet;
}
results.setAllCandidates(context.collectAllCandidates ? allCandidates : null);
return results;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -602,7 +620,7 @@ public class CallResolver {
for (ResolvedCallWithTrace<F> call : calls) {
task.tracing.bindReference(call.getTrace(), call);
task.tracing.bindResolvedCall(call.getTrace(), call);
task.getResolvedCalls().add(call);
task.addResolvedCall(call);
}
}
}
@@ -17,6 +17,7 @@
package org.jetbrains.jet.lang.resolve.calls.results;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
@@ -43,6 +44,10 @@ public interface OverloadResolutionResults<D extends CallableDescriptor> {
}
}
/* All candidates are collected only if ResolutionContext.collectAllCandidates is set to true */
@Nullable
Collection<ResolvedCall<D>> getAllCandidates();
@NotNull
Collection<? extends ResolvedCall<? extends D>> getResultingCalls();
@@ -17,8 +17,10 @@
package org.jetbrains.jet.lang.resolve.calls.results;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall;
import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCallWithTrace;
import java.util.Collection;
@@ -60,6 +62,7 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
private final Collection<ResolvedCallWithTrace<D>> results;
private final Code resultCode;
private DelegatingBindingTrace trace;
private Collection<ResolvedCall<D>> allCandidates;
private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection<ResolvedCallWithTrace<D>> results) {
this.results = results;
@@ -116,11 +119,6 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
return resultCode == Code.INCOMPLETE_TYPE_INFERENCE;
}
//
// public OverloadResolutionResultsImpl<D> newContents(@NotNull Collection<D> functionDescriptors) {
// return new OverloadResolutionResultsImpl<D>(resultCode, functionDescriptors);
// }
public DelegatingBindingTrace getTrace() {
return trace;
}
@@ -129,4 +127,14 @@ public class OverloadResolutionResultsImpl<D extends CallableDescriptor> impleme
this.trace = trace;
return this;
}
public void setAllCandidates(@Nullable Collection<ResolvedCall<D>> allCandidates) {
this.allCandidates = allCandidates;
}
@Nullable
@Override
public Collection<ResolvedCall<D>> getAllCandidates() {
return allCandidates;
}
}
@@ -39,7 +39,7 @@ public class ResolutionResultsHandler {
public <D extends CallableDescriptor> OverloadResolutionResultsImpl<D> computeResultAndReportErrors(
@NotNull BindingTrace trace,
@NotNull TracingStrategy tracing,
@NotNull Set<ResolvedCallWithTrace<D>> candidates
@NotNull Collection<ResolvedCallWithTrace<D>> candidates
) {
Set<ResolvedCallWithTrace<D>> successfulCandidates = Sets.newLinkedHashSet();
Set<ResolvedCallWithTrace<D>> failedCandidates = Sets.newLinkedHashSet();
@@ -16,7 +16,7 @@
package org.jetbrains.jet.lang.resolve.calls.tasks;
import com.google.common.collect.Sets;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
@@ -33,14 +33,13 @@ import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.expressions.LabelResolver;
import java.util.Collection;
import java.util.Set;
/**
* Stores candidates for call resolution.
*/
public class ResolutionTask<D extends CallableDescriptor, F extends D> extends CallResolutionContext<ResolutionTask<D, F>> {
private final Collection<ResolutionCandidate<D>> candidates;
private final Set<ResolvedCallWithTrace<F>> resolvedCalls = Sets.newLinkedHashSet();
private final Collection<ResolvedCallWithTrace<F>> resolvedCalls;
private DescriptorCheckStrategy checkingStrategy;
public final TracingStrategy tracing;
@@ -58,12 +57,14 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
@NotNull LabelResolver labelResolver,
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments,
@NotNull CallResolverExtension callResolverExtension,
@NotNull Collection<ResolvedCallWithTrace<F>> resolvedCalls,
boolean isAnnotationContext,
boolean collectAllCandidates
) {
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext, collectAllCandidates);
this.candidates = candidates;
this.resolvedCalls = resolvedCalls;
this.tracing = tracing;
}
@@ -76,7 +77,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
context.trace, context.scope, context.call,
context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments,
context.resolutionResultsCache, context.labelResolver, context.dataFlowInfoForArguments,
context.callResolverExtension, context.isAnnotationContext, context.collectAllCandidates);
context.callResolverExtension, Lists.<ResolvedCallWithTrace<F>>newArrayList(), context.isAnnotationContext, context.collectAllCandidates);
}
public ResolutionTask(
@@ -92,8 +93,12 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
return candidates;
}
public void addResolvedCall(@NotNull ResolvedCallWithTrace<F> resolvedCall) {
resolvedCalls.add(resolvedCall);
}
@NotNull
public Set<ResolvedCallWithTrace<F>> getResolvedCalls() {
public Collection<ResolvedCallWithTrace<F>> getResolvedCalls() {
return resolvedCalls;
}
@@ -121,7 +126,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
) {
ResolutionTask<D, F> newTask = new ResolutionTask<D, F>(
candidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext,
resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, resolvedCalls, isAnnotationContext,
collectAllCandidates);
newTask.setCheckingStrategy(checkingStrategy);
return newTask;
@@ -130,7 +135,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) {
return new ResolutionTask<D, F>(
candidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments,
resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension,
resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, resolvedCalls,
isAnnotationContext, collectAllCandidates);
}