Refactoring: do not store reference expression in resolution task

Sometimes there is no reference for the call (like '{ ... } ()').
A fake reference can be created, but the case when an error is reported on it can't be easily supported.

There were two usages of this reference: tracing and receiver for invoke.
Tracing strategy is created beforehand. Receiver for invoke uses the callee expression (from variable call), not the reference.
This commit is contained in:
Svetlana Isakova
2014-02-03 14:22:13 +04:00
parent 446aed5cf1
commit 495d6326e5
6 changed files with 76 additions and 63 deletions
@@ -110,11 +110,12 @@ public class CallResolver {
else { else {
callableDescriptorCollectors.add(CallableDescriptorCollectors.VARIABLES); callableDescriptorCollectors.add(CallableDescriptorCollectors.VARIABLES);
} }
TracingStrategy tracing = TracingStrategyImpl.create(nameExpression, context.call);
List<ResolutionTask<VariableDescriptor, VariableDescriptor>> prioritizedTasks = List<ResolutionTask<VariableDescriptor, VariableDescriptor>> prioritizedTasks =
TaskPrioritizer.<VariableDescriptor, VariableDescriptor>computePrioritizedTasks(context, referencedName, nameExpression, TaskPrioritizer.<VariableDescriptor, VariableDescriptor>computePrioritizedTasks(
callableDescriptorCollectors); context, referencedName, tracing, callableDescriptorCollectors);
return doResolveCallOrGetCachedResults(ResolutionResultsCache.PROPERTY_MEMBER_TYPE, return doResolveCallOrGetCachedResults(ResolutionResultsCache.PROPERTY_MEMBER_TYPE,
context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression); context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, tracing);
} }
@NotNull @NotNull
@@ -135,24 +136,33 @@ public class CallResolver {
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName( public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull JetReferenceExpression functionReference, @NotNull JetReferenceExpression functionReference,
@NotNull Name name) { @NotNull Name name
return resolveCallWithGivenName(context, functionReference, name, true); ) {
TracingStrategy tracing = TracingStrategyImpl.create(functionReference, context.call);
return resolveCallWithGivenName(context, name, tracing, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
}
@NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallForInvoke(
@NotNull BasicCallResolutionContext context,
@NotNull TracingStrategy tracing
) {
List<CallableDescriptorCollector<? extends CallableDescriptor>> collectors = Collections
.<CallableDescriptorCollector<? extends CallableDescriptor>>singletonList(CallableDescriptorCollectors.FUNCTIONS);
return resolveCallWithGivenName(context, Name.identifier("invoke"), tracing, collectors);
} }
@NotNull @NotNull
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName( public OverloadResolutionResults<FunctionDescriptor> resolveCallWithGivenName(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull JetReferenceExpression functionReference,
@NotNull Name name, @NotNull Name name,
boolean allowVariableWithInvoke @NotNull TracingStrategy tracing,
@NotNull List<CallableDescriptorCollector<? extends CallableDescriptor>> collectors
) { ) {
List<CallableDescriptorCollector<? extends CallableDescriptor>> collectors =
allowVariableWithInvoke ? CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES :
Collections.<CallableDescriptorCollector<? extends CallableDescriptor>>singletonList(CallableDescriptorCollectors.FUNCTIONS);
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks = List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks =
TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks(context, name, functionReference, collectors); TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks(context, name, tracing, collectors);
return doResolveCallOrGetCachedResults(ResolutionResultsCache.FUNCTION_MEMBER_TYPE, return doResolveCallOrGetCachedResults(ResolutionResultsCache.FUNCTION_MEMBER_TYPE,
context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing);
} }
@NotNull @NotNull
@@ -200,7 +210,9 @@ public class CallResolver {
Name name = expression.getReferencedNameAsName(); Name name = expression.getReferencedNameAsName();
prioritizedTasks = TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); TracingStrategy tracing = TracingStrategyImpl.create(expression, context.call);
prioritizedTasks = TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasks(
context, name, tracing, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES);
ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() { ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() {
@Override @Override
public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) { public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
@@ -248,7 +260,7 @@ public class CallResolver {
Collection<ResolutionCandidate<CallableDescriptor>> candidates = Collection<ResolutionCandidate<CallableDescriptor>> candidates =
TaskPrioritizer.<CallableDescriptor>convertWithImpliedThisAndNoReceiver(context.scope, constructors); TaskPrioritizer.<CallableDescriptor>convertWithImpliedThisAndNoReceiver(context.scope, constructors);
prioritizedTasks = TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates( prioritizedTasks = TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
context, functionReference, candidates, null); context, candidates, TracingStrategyImpl.create(functionReference, context.call));
} }
else { else {
context.trace.report(NOT_A_CLASS.on(calleeExpression)); context.trace.report(NOT_A_CLASS.on(calleeExpression));
@@ -296,7 +308,8 @@ public class CallResolver {
// so we wrap what we have into a fake reference and pass it on (unwrap on the other end) // so we wrap what we have into a fake reference and pass it on (unwrap on the other end)
functionReference = new JetFakeReference(calleeExpression); functionReference = new JetFakeReference(calleeExpression);
prioritizedTasks = Collections.singletonList(new ResolutionTask<CallableDescriptor, FunctionDescriptor>(Collections.singleton(resolutionCandidate), functionReference, context)); prioritizedTasks = Collections.singletonList(new ResolutionTask<CallableDescriptor, FunctionDescriptor>(
Collections.singleton(resolutionCandidate), functionReference, context));
} }
else { else {
// checkTypesWithNoCallee(trace, scope, call); // checkTypesWithNoCallee(trace, scope, call);
@@ -304,9 +317,10 @@ public class CallResolver {
} }
} }
TracingStrategy tracing = TracingStrategyImpl.create(functionReference, context.call);
OverloadResolutionResultsImpl<FunctionDescriptor> results = doResolveCallOrGetCachedResults( OverloadResolutionResultsImpl<FunctionDescriptor> results = doResolveCallOrGetCachedResults(
ResolutionResultsCache.FUNCTION_MEMBER_TYPE, context, prioritizedTasks, ResolutionResultsCache.FUNCTION_MEMBER_TYPE, context, prioritizedTasks,
CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing);
if (calleeExpression instanceof JetSimpleNameExpression) { if (calleeExpression instanceof JetSimpleNameExpression) {
ExpressionTypingUtils.checkCapturingInClosure((JetSimpleNameExpression) calleeExpression, context.trace, context.scope); ExpressionTypingUtils.checkCapturingInClosure((JetSimpleNameExpression) calleeExpression, context.trace, context.scope);
} }
@@ -315,8 +329,7 @@ public class CallResolver {
public OverloadResolutionResults<FunctionDescriptor> resolveCallWithKnownCandidate( public OverloadResolutionResults<FunctionDescriptor> resolveCallWithKnownCandidate(
@NotNull Call call, @NotNull Call call,
@Nullable TracingStrategy tracing, @NotNull TracingStrategy tracing,
@NotNull JetReferenceExpression reference,
@NotNull ResolutionContext<?> context, @NotNull ResolutionContext<?> context,
@NotNull ResolutionCandidate<CallableDescriptor> candidate, @NotNull ResolutionCandidate<CallableDescriptor> candidate,
@Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments
@@ -326,9 +339,9 @@ public class CallResolver {
List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks = List<ResolutionTask<CallableDescriptor, FunctionDescriptor>> tasks =
TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates( TaskPrioritizer.<CallableDescriptor, FunctionDescriptor>computePrioritizedTasksFromCandidates(
basicCallResolutionContext, reference, Collections.singleton(candidate), tracing); basicCallResolutionContext, Collections.singleton(candidate), tracing);
return doResolveCallOrGetCachedResults(ResolutionResultsCache.FUNCTION_MEMBER_TYPE, basicCallResolutionContext, tasks, return doResolveCallOrGetCachedResults(ResolutionResultsCache.FUNCTION_MEMBER_TYPE, basicCallResolutionContext, tasks,
CallTransformer.FUNCTION_CALL_TRANSFORMER, reference); CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing);
} }
private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCallOrGetCachedResults( private <D extends CallableDescriptor, F extends D> OverloadResolutionResultsImpl<F> doResolveCallOrGetCachedResults(
@@ -336,10 +349,9 @@ public class CallResolver {
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull List<ResolutionTask<D, F>> prioritizedTasks, @NotNull List<ResolutionTask<D, F>> prioritizedTasks,
@NotNull CallTransformer<D, F> callTransformer, @NotNull CallTransformer<D, F> callTransformer,
@NotNull JetReferenceExpression reference @NotNull TracingStrategy tracing
) { ) {
OverloadResolutionResultsImpl<F> results = null; OverloadResolutionResultsImpl<F> results = null;
TracingStrategy tracing = prioritizedTasks.isEmpty() ? TracingStrategy.EMPTY : prioritizedTasks.iterator().next().tracing;
TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call); TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call);
CallKey callKey = CallResolverUtil.createCallKey(context); CallKey callKey = CallResolverUtil.createCallKey(context);
if (callKey != null) { if (callKey != null) {
@@ -353,7 +365,7 @@ public class CallResolver {
} }
if (results == null) { if (results == null) {
BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall); BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall);
results = doResolveCall(newContext, prioritizedTasks, callTransformer, reference); results = doResolveCall(newContext, prioritizedTasks, callTransformer, tracing);
DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace(); DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace();
if (deltasTraceForTypeInference != null) { if (deltasTraceForTypeInference != null) {
deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall); deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall);
@@ -471,8 +483,8 @@ public class CallResolver {
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull List<ResolutionTask<D, F>> prioritizedTasks, // high to low priority @NotNull List<ResolutionTask<D, F>> prioritizedTasks, // high to low priority
@NotNull CallTransformer<D, F> callTransformer, @NotNull CallTransformer<D, F> callTransformer,
@NotNull JetReferenceExpression reference) { @NotNull TracingStrategy tracing
) {
ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create(); ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create();
context.trace.record(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement(), debugInfo); context.trace.record(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement(), debugInfo);
context.trace.record(RESOLUTION_SCOPE, context.call.getCalleeExpression(), context.scope); context.trace.record(RESOLUTION_SCOPE, context.call.getCalleeExpression(), context.scope);
@@ -490,7 +502,7 @@ public class CallResolver {
TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null; TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null;
OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null; OverloadResolutionResultsImpl<F> resultsForFirstNonemptyCandidateSet = null;
for (ResolutionTask<D, F> task : prioritizedTasks) { for (ResolutionTask<D, F> task : prioritizedTasks) {
TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.reference); TemporaryBindingTrace taskTrace = TemporaryBindingTrace.create(context.trace, "trace to resolve a task for", task.call.getCalleeExpression());
OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments( OverloadResolutionResultsImpl<F> results = performResolutionGuardedForExtraFunctionLiteralArguments(
task.replaceBindingTrace(taskTrace), callTransformer); task.replaceBindingTrace(taskTrace), callTransformer);
if (results.isSuccess() || results.isAmbiguity()) { if (results.isSuccess() || results.isAmbiguity()) {
@@ -521,7 +533,7 @@ public class CallResolver {
} }
} }
else { else {
context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference)); tracing.unresolvedReference(context.trace);
argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS); argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS);
} }
return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound(); return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.<F>nameNotFound();
@@ -40,7 +40,6 @@ import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionCandidate;
import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask; import org.jetbrains.jet.lang.resolve.calls.tasks.ResolutionTask;
import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall; import org.jetbrains.jet.lang.resolve.calls.util.DelegatingCall;
import org.jetbrains.jet.lang.resolve.name.Name;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.jet.lang.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue;
import org.jetbrains.jet.lang.types.JetType; import org.jetbrains.jet.lang.types.JetType;
@@ -176,9 +175,11 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
@NotNull @NotNull
@Override @Override
public Collection<ResolvedCallWithTrace<FunctionDescriptor>> transformCall(@NotNull CallCandidateResolutionContext<CallableDescriptor> context, public Collection<ResolvedCallWithTrace<FunctionDescriptor>> transformCall(
@NotNull CallResolver callResolver, @NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task) { @NotNull CallCandidateResolutionContext<CallableDescriptor> context,
@NotNull CallResolver callResolver,
@NotNull ResolutionTask<CallableDescriptor, FunctionDescriptor> task
) {
CallableDescriptor descriptor = context.candidateCall.getCandidateDescriptor(); CallableDescriptor descriptor = context.candidateCall.getCandidateDescriptor();
if (descriptor instanceof FunctionDescriptor) { if (descriptor instanceof FunctionDescriptor) {
return super.transformCall(context, callResolver, task); return super.transformCall(context, callResolver, task);
@@ -192,7 +193,11 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
final ResolvedCallWithTrace<VariableDescriptor> variableResolvedCall = (ResolvedCallWithTrace)context.candidateCall; final ResolvedCallWithTrace<VariableDescriptor> variableResolvedCall = (ResolvedCallWithTrace)context.candidateCall;
Call functionCall = new CallForImplicitInvoke(context.explicitExtensionReceiverForInvoke, task, returnType); JetExpression calleeExpression = task.call.getCalleeExpression();
if (calleeExpression == null) return Collections.emptyList();
ExpressionReceiver variableReceiver = new ExpressionReceiver(calleeExpression, variableResolvedCall.getResultingDescriptor().getType());
Call functionCall = new CallForImplicitInvoke(context.explicitExtensionReceiverForInvoke, variableReceiver, task.call);
DelegatingBindingTrace variableCallTrace = context.candidateCall.getTrace(); DelegatingBindingTrace variableCallTrace = context.candidateCall.getTrace();
BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create( BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create(
@@ -200,8 +205,8 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
functionCall, context.checkArguments, context.dataFlowInfoForArguments); functionCall, context.checkArguments, context.dataFlowInfoForArguments);
// 'invoke' call resolve // 'invoke' call resolve
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithGivenName( OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallForInvoke(
basicCallResolutionContext, task.reference, Name.identifier("invoke"), false); basicCallResolutionContext, context.tracing); //todo context.tracing is incorrect
Collection<ResolvedCallWithTrace<FunctionDescriptor>> calls = ((OverloadResolutionResultsImpl<FunctionDescriptor>)results).getResultingCalls(); Collection<ResolvedCallWithTrace<FunctionDescriptor>> calls = ((OverloadResolutionResultsImpl<FunctionDescriptor>)results).getResultingCalls();
return Collections2.transform(calls, new Function<ResolvedCallWithTrace<FunctionDescriptor>, ResolvedCallWithTrace<FunctionDescriptor>>() { return Collections2.transform(calls, new Function<ResolvedCallWithTrace<FunctionDescriptor>, ResolvedCallWithTrace<FunctionDescriptor>>() {
@@ -219,14 +224,18 @@ public class CallTransformer<D extends CallableDescriptor, F extends D> {
final ExpressionReceiver calleeExpressionAsThisObject; final ExpressionReceiver calleeExpressionAsThisObject;
final JetSimpleNameExpression fakeInvokeExpression; final JetSimpleNameExpression fakeInvokeExpression;
private CallForImplicitInvoke(ReceiverValue explicitExtensionReceiver, private CallForImplicitInvoke(
ResolutionTask<CallableDescriptor, FunctionDescriptor> task, JetType returnType) { @NotNull ReceiverValue explicitExtensionReceiver,
super(task.call); @NotNull ExpressionReceiver calleeExpressionAsThisObject,
this.outerCall = task.call; @NotNull Call call
) {
super(call);
this.outerCall = call;
this.explicitExtensionReceiver = explicitExtensionReceiver; this.explicitExtensionReceiver = explicitExtensionReceiver;
this.calleeExpressionAsThisObject = new ExpressionReceiver(task.reference, returnType); this.calleeExpressionAsThisObject = calleeExpressionAsThisObject;
this.fakeInvokeExpression = (JetSimpleNameExpression) JetPsiFactory.createExpression(task.call.getCallElement().getProject(), "invoke"); this.fakeInvokeExpression = (JetSimpleNameExpression) JetPsiFactory.createExpression(call.getCallElement().getProject(), "invoke");
} }
@NotNull @NotNull
@Override @Override
public ReceiverValue getExplicitReceiver() { public ReceiverValue getExplicitReceiver() {
@@ -42,11 +42,10 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
private final Collection<ResolutionCandidate<D>> candidates; private final Collection<ResolutionCandidate<D>> candidates;
private final Set<ResolvedCallWithTrace<F>> resolvedCalls = Sets.newLinkedHashSet(); private final Set<ResolvedCallWithTrace<F>> resolvedCalls = Sets.newLinkedHashSet();
private DescriptorCheckStrategy checkingStrategy; private DescriptorCheckStrategy checkingStrategy;
public final JetReferenceExpression reference;
public final TracingStrategy tracing; public final TracingStrategy tracing;
public ResolutionTask( public ResolutionTask(
@NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull JetReferenceExpression reference, @NotNull Collection<ResolutionCandidate<D>> candidates,
@NotNull TracingStrategy tracing, BindingTrace trace, JetScope scope, Call call, JetType expectedType, @NotNull TracingStrategy tracing, BindingTrace trace, JetScope scope, Call call, JetType expectedType,
DataFlowInfo dataFlowInfo, ContextDependency contextDependency, CheckValueArgumentsMode checkArguments, DataFlowInfo dataFlowInfo, ContextDependency contextDependency, CheckValueArgumentsMode checkArguments,
ResolutionResultsCache resolutionResultsCache, @NotNull LabelResolver labelResolver, ResolutionResultsCache resolutionResultsCache, @NotNull LabelResolver labelResolver,
@@ -56,17 +55,15 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache,
labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext); labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext);
this.candidates = candidates; this.candidates = candidates;
this.reference = reference;
this.tracing = tracing; this.tracing = tracing;
} }
public ResolutionTask( public ResolutionTask(
@NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull Collection<ResolutionCandidate<D>> candidates,
@NotNull JetReferenceExpression reference,
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@Nullable TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
this(candidates, reference, tracing != null ? tracing : TracingStrategyImpl.create(reference, context.call), this(candidates, tracing,
context.trace, context.scope, context.call, context.trace, context.scope, context.call,
context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments, context.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments,
context.resolutionResultsCache, context.labelResolver, context.dataFlowInfoForArguments, context.resolutionResultsCache, context.labelResolver, context.dataFlowInfoForArguments,
@@ -78,7 +75,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
@NotNull JetReferenceExpression reference, @NotNull JetReferenceExpression reference,
@NotNull BasicCallResolutionContext context @NotNull BasicCallResolutionContext context
) { ) {
this(candidates, reference, context, null); this(candidates, context, TracingStrategyImpl.create(reference, context.call));
} }
@NotNull @NotNull
@@ -113,7 +110,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
@NotNull LabelResolver labelResolver @NotNull LabelResolver labelResolver
) { ) {
ResolutionTask<D, F> newTask = new ResolutionTask<D, F>( ResolutionTask<D, F> newTask = new ResolutionTask<D, F>(
candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, candidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments,
resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext); resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext);
newTask.setCheckingStrategy(checkingStrategy); newTask.setCheckingStrategy(checkingStrategy);
return newTask; return newTask;
@@ -121,7 +118,7 @@ public class ResolutionTask<D extends CallableDescriptor, F extends D> extends C
public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) { public ResolutionTask<D, F> replaceCall(@NotNull Call newCall) {
return new ResolutionTask<D, F>( return new ResolutionTask<D, F>(
candidates, reference, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, candidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments,
resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext); resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext);
} }
@@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls.tasks;
import com.google.common.base.Predicate; import com.google.common.base.Predicate;
import com.google.common.collect.Collections2; import com.google.common.collect.Collections2;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.CallableDescriptor;
@@ -31,7 +30,6 @@ import java.util.Collection;
import java.util.List; import java.util.List;
public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> { public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
private final JetReferenceExpression reference;
private final BasicCallResolutionContext basicCallResolutionContext; private final BasicCallResolutionContext basicCallResolutionContext;
private final PriorityProvider<ResolutionCandidate<D>> priorityProvider; private final PriorityProvider<ResolutionCandidate<D>> priorityProvider;
private final TracingStrategy tracing; private final TracingStrategy tracing;
@@ -41,12 +39,11 @@ public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
private List<ResolutionTask<D, F>> tasks = null; private List<ResolutionTask<D, F>> tasks = null;
public ResolutionTaskHolder(@NotNull JetReferenceExpression reference, public ResolutionTaskHolder(
@NotNull BasicCallResolutionContext basicCallResolutionContext, @NotNull BasicCallResolutionContext basicCallResolutionContext,
@NotNull PriorityProvider<ResolutionCandidate<D>> priorityProvider, @NotNull PriorityProvider<ResolutionCandidate<D>> priorityProvider,
@Nullable TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
this.reference = reference;
this.basicCallResolutionContext = basicCallResolutionContext; this.basicCallResolutionContext = basicCallResolutionContext;
this.priorityProvider = priorityProvider; this.priorityProvider = priorityProvider;
this.tracing = tracing; this.tracing = tracing;
@@ -86,7 +83,7 @@ public class ResolutionTaskHolder<D extends CallableDescriptor, F extends D> {
} }
}); });
if (!filteredCandidates.isEmpty()) { if (!filteredCandidates.isEmpty()) {
tasks.add(new ResolutionTask<D, F>(filteredCandidates, reference, basicCallResolutionContext, tracing)); tasks.add(new ResolutionTask<D, F>(filteredCandidates, basicCallResolutionContext, tracing));
} }
} }
} }
@@ -79,7 +79,7 @@ public class TaskPrioritizer {
public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasks( public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasks(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull Name name, @NotNull Name name,
@NotNull JetReferenceExpression functionReference, @NotNull TracingStrategy tracing,
@NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors @NotNull List<CallableDescriptorCollector<? extends D>> callableDescriptorCollectors
) { ) {
List<Pair<JetScope, ReceiverValue>> variants = new ArrayList<Pair<JetScope, ReceiverValue>>(2); List<Pair<JetScope, ReceiverValue>> variants = new ArrayList<Pair<JetScope, ReceiverValue>>(2);
@@ -98,7 +98,7 @@ public class TaskPrioritizer {
} }
ResolutionTaskHolder<D, F> result = ResolutionTaskHolder<D, F> result =
new ResolutionTaskHolder<D, F>(functionReference, context, new MyPriorityProvider<D>(context), null); new ResolutionTaskHolder<D, F>(context, new MyPriorityProvider<D>(context), tracing);
for (Pair<JetScope, ReceiverValue> pair : variants) { for (Pair<JetScope, ReceiverValue> pair : variants) {
doComputeTasks(pair.second, new TaskPrioritizerContext<D, F>(name, result, context, pair.first, callableDescriptorCollectors)); doComputeTasks(pair.second, new TaskPrioritizerContext<D, F>(name, result, context, pair.first, callableDescriptorCollectors));
} }
@@ -332,12 +332,11 @@ public class TaskPrioritizer {
public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasksFromCandidates( public static <D extends CallableDescriptor, F extends D> List<ResolutionTask<D, F>> computePrioritizedTasksFromCandidates(
@NotNull BasicCallResolutionContext context, @NotNull BasicCallResolutionContext context,
@NotNull JetReferenceExpression functionReference,
@NotNull Collection<ResolutionCandidate<D>> candidates, @NotNull Collection<ResolutionCandidate<D>> candidates,
@Nullable TracingStrategy tracing @NotNull TracingStrategy tracing
) { ) {
ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>( ResolutionTaskHolder<D, F> result = new ResolutionTaskHolder<D, F>(
functionReference, context, new MyPriorityProvider<D>(context), tracing); context, new MyPriorityProvider<D>(context), tracing);
result.addCandidates(candidates); result.addCandidates(candidates);
return result.getTasks(); return result.getTasks();
} }
@@ -72,13 +72,11 @@ public class ControlStructureTypingUtils {
) { ) {
SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction(
constructionName.toUpperCase(), argumentNames, isArgumentNullable); constructionName.toUpperCase(), argumentNames, isArgumentNullable);
JetReferenceExpression reference = JetPsiFactory.createSimpleName(
expressionTypingServices.getProject(), "fake" + constructionName + "Call");
TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName);
ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(function, null); ResolutionCandidate<CallableDescriptor> resolutionCandidate = ResolutionCandidate.<CallableDescriptor>create(function, null);
CallResolver callResolver = expressionTypingServices.getCallResolver(); CallResolver callResolver = expressionTypingServices.getCallResolver();
OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate( OverloadResolutionResults<FunctionDescriptor> results = callResolver.resolveCallWithKnownCandidate(
call, tracing, reference, context, resolutionCandidate, dataFlowInfoForArguments); call, tracing, context, resolutionCandidate, dataFlowInfoForArguments);
assert results.isSingleResult() : "Not single result after resolving one known candidate"; assert results.isSingleResult() : "Not single result after resolving one known candidate";
return results.getResultingCall(); return results.getResultingCall();
} }
@@ -242,6 +240,7 @@ public class ControlStructureTypingUtils {
}; };
} }
@NotNull
/*package*/ static TracingStrategy createTracingForSpecialConstruction( /*package*/ static TracingStrategy createTracingForSpecialConstruction(
final @NotNull Call call, final @NotNull Call call,
final @NotNull String constructionName final @NotNull String constructionName