Collect all resolved candidate calls if required
This commit is contained in:
committed by
Andrey Breslav
parent
e6a71563ba
commit
77880f667a
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+5
@@ -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();
|
||||
|
||||
|
||||
+13
-5
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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();
|
||||
|
||||
+12
-7
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user