From 77880f667a20ab6b90749bb291254f750fe0b270 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Thu, 20 Mar 2014 13:56:16 +0400 Subject: [PATCH] Collect all resolved candidate calls if required --- .../jet/lang/resolve/calls/CallResolver.java | 36 ++++++++++++++----- .../results/OverloadResolutionResults.java | 5 +++ .../OverloadResolutionResultsImpl.java | 18 +++++++--- .../results/ResolutionResultsHandler.java | 2 +- .../resolve/calls/tasks/ResolutionTask.java | 19 ++++++---- 5 files changed, 58 insertions(+), 22 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java index 2f01f6b579a..e23880d8b42 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallResolver.java @@ -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> allCandidates = Lists.newArrayList(); + OverloadResolutionResultsImpl successfulResults = null; TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null; OverloadResolutionResultsImpl resultsForFirstNonemptyCandidateSet = null; for (ResolutionTask task : prioritizedTasks) { + if (successfulResults != null && !context.collectAllCandidates) continue; + TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.call.getCalleeExpression()); OverloadResolutionResultsImpl 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 results; + if (successfulResults != null) { + results = successfulResults; + } + else if (traceForFirstNonemptyCandidateSet == null) { tracing.unresolvedReference(context.trace); argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS); - return OverloadResolutionResultsImpl.nameNotFound(); + results = OverloadResolutionResultsImpl.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 call : calls) { task.tracing.bindReference(call.getTrace(), call); task.tracing.bindResolvedCall(call.getTrace(), call); - task.getResolvedCalls().add(call); + task.addResolvedCall(call); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java index 1b7f0eb48c1..03a1cbb60e4 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/results/OverloadResolutionResults.java @@ -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 { } } + /* All candidates are collected only if ResolutionContext.collectAllCandidates is set to true */ + @Nullable + Collection> getAllCandidates(); + @NotNull Collection> getResultingCalls(); 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 0dce2322f94..1c58bfa415a 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 @@ -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 impleme private final Collection> results; private final Code resultCode; private DelegatingBindingTrace trace; + private Collection> allCandidates; private OverloadResolutionResultsImpl(@NotNull Code resultCode, @NotNull Collection> results) { this.results = results; @@ -116,11 +119,6 @@ public class OverloadResolutionResultsImpl impleme return resultCode == Code.INCOMPLETE_TYPE_INFERENCE; } - // -// public OverloadResolutionResultsImpl newContents(@NotNull Collection functionDescriptors) { -// return new OverloadResolutionResultsImpl(resultCode, functionDescriptors); -// } - public DelegatingBindingTrace getTrace() { return trace; } @@ -129,4 +127,14 @@ public class OverloadResolutionResultsImpl impleme this.trace = trace; return this; } + + public void setAllCandidates(@Nullable Collection> allCandidates) { + this.allCandidates = allCandidates; + } + + @Nullable + @Override + public Collection> getAllCandidates() { + return allCandidates; + } } 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 f7798fe2acc..954f52766ed 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 @@ -39,7 +39,7 @@ public class ResolutionResultsHandler { public OverloadResolutionResultsImpl computeResultAndReportErrors( @NotNull BindingTrace trace, @NotNull TracingStrategy tracing, - @NotNull Set> candidates + @NotNull Collection> candidates ) { Set> successfulCandidates = Sets.newLinkedHashSet(); Set> failedCandidates = Sets.newLinkedHashSet(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java index 2d349b5d1f4..9433eed6940 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTask.java @@ -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 extends CallResolutionContext> { private final Collection> candidates; - private final Set> resolvedCalls = Sets.newLinkedHashSet(); + private final Collection> resolvedCalls; private DescriptorCheckStrategy checkingStrategy; public final TracingStrategy tracing; @@ -58,12 +57,14 @@ public class ResolutionTask extends C @NotNull LabelResolver labelResolver, @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments, @NotNull CallResolverExtension callResolverExtension, + @NotNull Collection> 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 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.>newArrayList(), context.isAnnotationContext, context.collectAllCandidates); } public ResolutionTask( @@ -92,8 +93,12 @@ public class ResolutionTask extends C return candidates; } + public void addResolvedCall(@NotNull ResolvedCallWithTrace resolvedCall) { + resolvedCalls.add(resolvedCall); + } + @NotNull - public Set> getResolvedCalls() { + public Collection> getResolvedCalls() { return resolvedCalls; } @@ -121,7 +126,7 @@ public class ResolutionTask extends C ) { ResolutionTask newTask = new ResolutionTask( 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 extends C public ResolutionTask replaceCall(@NotNull Call newCall) { return new ResolutionTask( candidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, - resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, + resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, resolvedCalls, isAnnotationContext, collectAllCandidates); }