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 4174f804622..bf50c0e3723 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 @@ -110,11 +110,12 @@ public class CallResolver { else { callableDescriptorCollectors.add(CallableDescriptorCollectors.VARIABLES); } + TracingStrategy tracing = TracingStrategyImpl.create(nameExpression, context.call); List> prioritizedTasks = - TaskPrioritizer.computePrioritizedTasks(context, referencedName, nameExpression, - callableDescriptorCollectors); + TaskPrioritizer.computePrioritizedTasks( + context, referencedName, tracing, callableDescriptorCollectors); return doResolveCallOrGetCachedResults(ResolutionResultsCache.PROPERTY_MEMBER_TYPE, - context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, nameExpression); + context, prioritizedTasks, CallTransformer.PROPERTY_CALL_TRANSFORMER, tracing); } @NotNull @@ -135,24 +136,33 @@ public class CallResolver { public OverloadResolutionResults resolveCallWithGivenName( @NotNull BasicCallResolutionContext context, @NotNull JetReferenceExpression functionReference, - @NotNull Name name) { - return resolveCallWithGivenName(context, functionReference, name, true); + @NotNull Name name + ) { + TracingStrategy tracing = TracingStrategyImpl.create(functionReference, context.call); + return resolveCallWithGivenName(context, name, tracing, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); + } + + @NotNull + public OverloadResolutionResults resolveCallForInvoke( + @NotNull BasicCallResolutionContext context, + @NotNull TracingStrategy tracing + ) { + List> collectors = Collections + .>singletonList(CallableDescriptorCollectors.FUNCTIONS); + return resolveCallWithGivenName(context, Name.identifier("invoke"), tracing, collectors); } @NotNull public OverloadResolutionResults resolveCallWithGivenName( @NotNull BasicCallResolutionContext context, - @NotNull JetReferenceExpression functionReference, @NotNull Name name, - boolean allowVariableWithInvoke + @NotNull TracingStrategy tracing, + @NotNull List> collectors ) { - List> collectors = - allowVariableWithInvoke ? CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES : - Collections.>singletonList(CallableDescriptorCollectors.FUNCTIONS); List> tasks = - TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, collectors); + TaskPrioritizer.computePrioritizedTasks(context, name, tracing, collectors); return doResolveCallOrGetCachedResults(ResolutionResultsCache.FUNCTION_MEMBER_TYPE, - context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); + context, tasks, CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing); } @NotNull @@ -200,7 +210,9 @@ public class CallResolver { Name name = expression.getReferencedNameAsName(); - prioritizedTasks = TaskPrioritizer.computePrioritizedTasks(context, name, functionReference, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); + TracingStrategy tracing = TracingStrategyImpl.create(expression, context.call); + prioritizedTasks = TaskPrioritizer.computePrioritizedTasks( + context, name, tracing, CallableDescriptorCollectors.FUNCTIONS_AND_VARIABLES); ResolutionTask.DescriptorCheckStrategy abstractConstructorCheck = new ResolutionTask.DescriptorCheckStrategy() { @Override public boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) { @@ -248,7 +260,7 @@ public class CallResolver { Collection> candidates = TaskPrioritizer.convertWithImpliedThisAndNoReceiver(context.scope, constructors); prioritizedTasks = TaskPrioritizer.computePrioritizedTasksFromCandidates( - context, functionReference, candidates, null); + context, candidates, TracingStrategyImpl.create(functionReference, context.call)); } else { 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) functionReference = new JetFakeReference(calleeExpression); - prioritizedTasks = Collections.singletonList(new ResolutionTask(Collections.singleton(resolutionCandidate), functionReference, context)); + prioritizedTasks = Collections.singletonList(new ResolutionTask( + Collections.singleton(resolutionCandidate), functionReference, context)); } else { // checkTypesWithNoCallee(trace, scope, call); @@ -304,9 +317,10 @@ public class CallResolver { } } + TracingStrategy tracing = TracingStrategyImpl.create(functionReference, context.call); OverloadResolutionResultsImpl results = doResolveCallOrGetCachedResults( ResolutionResultsCache.FUNCTION_MEMBER_TYPE, context, prioritizedTasks, - CallTransformer.FUNCTION_CALL_TRANSFORMER, functionReference); + CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing); if (calleeExpression instanceof JetSimpleNameExpression) { ExpressionTypingUtils.checkCapturingInClosure((JetSimpleNameExpression) calleeExpression, context.trace, context.scope); } @@ -315,8 +329,7 @@ public class CallResolver { public OverloadResolutionResults resolveCallWithKnownCandidate( @NotNull Call call, - @Nullable TracingStrategy tracing, - @NotNull JetReferenceExpression reference, + @NotNull TracingStrategy tracing, @NotNull ResolutionContext context, @NotNull ResolutionCandidate candidate, @Nullable MutableDataFlowInfoForArguments dataFlowInfoForArguments @@ -326,9 +339,9 @@ public class CallResolver { List> tasks = TaskPrioritizer.computePrioritizedTasksFromCandidates( - basicCallResolutionContext, reference, Collections.singleton(candidate), tracing); + basicCallResolutionContext, Collections.singleton(candidate), tracing); return doResolveCallOrGetCachedResults(ResolutionResultsCache.FUNCTION_MEMBER_TYPE, basicCallResolutionContext, tasks, - CallTransformer.FUNCTION_CALL_TRANSFORMER, reference); + CallTransformer.FUNCTION_CALL_TRANSFORMER, tracing); } private OverloadResolutionResultsImpl doResolveCallOrGetCachedResults( @@ -336,10 +349,9 @@ public class CallResolver { @NotNull BasicCallResolutionContext context, @NotNull List> prioritizedTasks, @NotNull CallTransformer callTransformer, - @NotNull JetReferenceExpression reference + @NotNull TracingStrategy tracing ) { OverloadResolutionResultsImpl results = null; - TracingStrategy tracing = prioritizedTasks.isEmpty() ? TracingStrategy.EMPTY : prioritizedTasks.iterator().next().tracing; TemporaryBindingTrace traceToResolveCall = TemporaryBindingTrace.create(context.trace, "trace to resolve call", context.call); CallKey callKey = CallResolverUtil.createCallKey(context); if (callKey != null) { @@ -353,7 +365,7 @@ public class CallResolver { } if (results == null) { BasicCallResolutionContext newContext = context.replaceBindingTrace(traceToResolveCall); - results = doResolveCall(newContext, prioritizedTasks, callTransformer, reference); + results = doResolveCall(newContext, prioritizedTasks, callTransformer, tracing); DelegatingBindingTrace deltasTraceForTypeInference = ((OverloadResolutionResultsImpl) results).getTrace(); if (deltasTraceForTypeInference != null) { deltasTraceForTypeInference.addAllMyDataTo(traceToResolveCall); @@ -471,8 +483,8 @@ public class CallResolver { @NotNull BasicCallResolutionContext context, @NotNull List> prioritizedTasks, // high to low priority @NotNull CallTransformer callTransformer, - @NotNull JetReferenceExpression reference) { - + @NotNull TracingStrategy tracing + ) { ResolutionDebugInfo.Data debugInfo = ResolutionDebugInfo.create(); context.trace.record(ResolutionDebugInfo.RESOLUTION_DEBUG_INFO, context.call.getCallElement(), debugInfo); context.trace.record(RESOLUTION_SCOPE, context.call.getCalleeExpression(), context.scope); @@ -490,7 +502,7 @@ public class CallResolver { TemporaryBindingTrace traceForFirstNonemptyCandidateSet = null; OverloadResolutionResultsImpl resultsForFirstNonemptyCandidateSet = null; for (ResolutionTask 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 results = performResolutionGuardedForExtraFunctionLiteralArguments( task.replaceBindingTrace(taskTrace), callTransformer); if (results.isSuccess() || results.isAmbiguity()) { @@ -521,7 +533,7 @@ public class CallResolver { } } else { - context.trace.report(UNRESOLVED_REFERENCE.on(reference, reference)); + tracing.unresolvedReference(context.trace); argumentTypeResolver.checkTypesWithNoCallee(context, SHAPE_FUNCTION_ARGUMENTS); } return resultsForFirstNonemptyCandidateSet != null ? resultsForFirstNonemptyCandidateSet : OverloadResolutionResultsImpl.nameNotFound(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java index 4f38c12154f..834e108f738 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/CallTransformer.java @@ -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.ResolutionTask; 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.ReceiverValue; import org.jetbrains.jet.lang.types.JetType; @@ -176,9 +175,11 @@ public class CallTransformer { @NotNull @Override - public Collection> transformCall(@NotNull CallCandidateResolutionContext context, - @NotNull CallResolver callResolver, @NotNull ResolutionTask task) { - + public Collection> transformCall( + @NotNull CallCandidateResolutionContext context, + @NotNull CallResolver callResolver, + @NotNull ResolutionTask task + ) { CallableDescriptor descriptor = context.candidateCall.getCandidateDescriptor(); if (descriptor instanceof FunctionDescriptor) { return super.transformCall(context, callResolver, task); @@ -192,7 +193,11 @@ public class CallTransformer { final ResolvedCallWithTrace 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(); BasicCallResolutionContext basicCallResolutionContext = BasicCallResolutionContext.create( @@ -200,8 +205,8 @@ public class CallTransformer { functionCall, context.checkArguments, context.dataFlowInfoForArguments); // 'invoke' call resolve - OverloadResolutionResults results = callResolver.resolveCallWithGivenName( - basicCallResolutionContext, task.reference, Name.identifier("invoke"), false); + OverloadResolutionResults results = callResolver.resolveCallForInvoke( + basicCallResolutionContext, context.tracing); //todo context.tracing is incorrect Collection> calls = ((OverloadResolutionResultsImpl)results).getResultingCalls(); return Collections2.transform(calls, new Function, ResolvedCallWithTrace>() { @@ -219,14 +224,18 @@ public class CallTransformer { final ExpressionReceiver calleeExpressionAsThisObject; final JetSimpleNameExpression fakeInvokeExpression; - private CallForImplicitInvoke(ReceiverValue explicitExtensionReceiver, - ResolutionTask task, JetType returnType) { - super(task.call); - this.outerCall = task.call; + private CallForImplicitInvoke( + @NotNull ReceiverValue explicitExtensionReceiver, + @NotNull ExpressionReceiver calleeExpressionAsThisObject, + @NotNull Call call + ) { + super(call); + this.outerCall = call; this.explicitExtensionReceiver = explicitExtensionReceiver; - this.calleeExpressionAsThisObject = new ExpressionReceiver(task.reference, returnType); - this.fakeInvokeExpression = (JetSimpleNameExpression) JetPsiFactory.createExpression(task.call.getCallElement().getProject(), "invoke"); + this.calleeExpressionAsThisObject = calleeExpressionAsThisObject; + this.fakeInvokeExpression = (JetSimpleNameExpression) JetPsiFactory.createExpression(call.getCallElement().getProject(), "invoke"); } + @NotNull @Override public ReceiverValue getExplicitReceiver() { 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 28c9e32457b..ab976f8a2ac 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 @@ -42,11 +42,10 @@ public class ResolutionTask extends C private final Collection> candidates; private final Set> resolvedCalls = Sets.newLinkedHashSet(); private DescriptorCheckStrategy checkingStrategy; - public final JetReferenceExpression reference; public final TracingStrategy tracing; public ResolutionTask( - @NotNull Collection> candidates, @NotNull JetReferenceExpression reference, + @NotNull Collection> candidates, @NotNull TracingStrategy tracing, BindingTrace trace, JetScope scope, Call call, JetType expectedType, DataFlowInfo dataFlowInfo, ContextDependency contextDependency, CheckValueArgumentsMode checkArguments, ResolutionResultsCache resolutionResultsCache, @NotNull LabelResolver labelResolver, @@ -56,17 +55,15 @@ public class ResolutionTask extends C super(trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext); this.candidates = candidates; - this.reference = reference; this.tracing = tracing; } public ResolutionTask( @NotNull Collection> candidates, - @NotNull JetReferenceExpression reference, @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.expectedType, context.dataFlowInfo, context.contextDependency, context.checkArguments, context.resolutionResultsCache, context.labelResolver, context.dataFlowInfoForArguments, @@ -78,7 +75,7 @@ public class ResolutionTask extends C @NotNull JetReferenceExpression reference, @NotNull BasicCallResolutionContext context ) { - this(candidates, reference, context, null); + this(candidates, context, TracingStrategyImpl.create(reference, context.call)); } @NotNull @@ -113,7 +110,7 @@ public class ResolutionTask extends C @NotNull LabelResolver labelResolver ) { ResolutionTask newTask = new ResolutionTask( - candidates, reference, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, + candidates, tracing, trace, scope, call, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext); newTask.setCheckingStrategy(checkingStrategy); return newTask; @@ -121,7 +118,7 @@ public class ResolutionTask extends C public ResolutionTask replaceCall(@NotNull Call newCall) { return new ResolutionTask( - candidates, reference, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, + candidates, tracing, trace, scope, newCall, expectedType, dataFlowInfo, contextDependency, checkArguments, resolutionResultsCache, labelResolver, dataFlowInfoForArguments, callResolverExtension, isAnnotationContext); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java index 3ce08b229c1..0a5ca948adc 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/ResolutionTaskHolder.java @@ -19,7 +19,6 @@ package org.jetbrains.jet.lang.resolve.calls.tasks; import com.google.common.base.Predicate; import com.google.common.collect.Collections2; import com.google.common.collect.Lists; -import com.google.common.collect.Sets; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; @@ -31,7 +30,6 @@ import java.util.Collection; import java.util.List; public class ResolutionTaskHolder { - private final JetReferenceExpression reference; private final BasicCallResolutionContext basicCallResolutionContext; private final PriorityProvider> priorityProvider; private final TracingStrategy tracing; @@ -41,12 +39,11 @@ public class ResolutionTaskHolder { private List> tasks = null; - public ResolutionTaskHolder(@NotNull JetReferenceExpression reference, + public ResolutionTaskHolder( @NotNull BasicCallResolutionContext basicCallResolutionContext, @NotNull PriorityProvider> priorityProvider, - @Nullable TracingStrategy tracing + @NotNull TracingStrategy tracing ) { - this.reference = reference; this.basicCallResolutionContext = basicCallResolutionContext; this.priorityProvider = priorityProvider; this.tracing = tracing; @@ -86,7 +83,7 @@ public class ResolutionTaskHolder { } }); if (!filteredCandidates.isEmpty()) { - tasks.add(new ResolutionTask(filteredCandidates, reference, basicCallResolutionContext, tracing)); + tasks.add(new ResolutionTask(filteredCandidates, basicCallResolutionContext, tracing)); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java index 82a32324b1f..22f01de015d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/tasks/TaskPrioritizer.java @@ -79,7 +79,7 @@ public class TaskPrioritizer { public static List> computePrioritizedTasks( @NotNull BasicCallResolutionContext context, @NotNull Name name, - @NotNull JetReferenceExpression functionReference, + @NotNull TracingStrategy tracing, @NotNull List> callableDescriptorCollectors ) { List> variants = new ArrayList>(2); @@ -98,7 +98,7 @@ public class TaskPrioritizer { } ResolutionTaskHolder result = - new ResolutionTaskHolder(functionReference, context, new MyPriorityProvider(context), null); + new ResolutionTaskHolder(context, new MyPriorityProvider(context), tracing); for (Pair pair : variants) { doComputeTasks(pair.second, new TaskPrioritizerContext(name, result, context, pair.first, callableDescriptorCollectors)); } @@ -332,12 +332,11 @@ public class TaskPrioritizer { public static List> computePrioritizedTasksFromCandidates( @NotNull BasicCallResolutionContext context, - @NotNull JetReferenceExpression functionReference, @NotNull Collection> candidates, - @Nullable TracingStrategy tracing + @NotNull TracingStrategy tracing ) { ResolutionTaskHolder result = new ResolutionTaskHolder( - functionReference, context, new MyPriorityProvider(context), tracing); + context, new MyPriorityProvider(context), tracing); result.addCandidates(candidates); return result.getTasks(); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java index ee7c0ac9fa1..37bc85a7a8d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/ControlStructureTypingUtils.java @@ -72,13 +72,11 @@ public class ControlStructureTypingUtils { ) { SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( constructionName.toUpperCase(), argumentNames, isArgumentNullable); - JetReferenceExpression reference = JetPsiFactory.createSimpleName( - expressionTypingServices.getProject(), "fake" + constructionName + "Call"); TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(function, null); CallResolver callResolver = expressionTypingServices.getCallResolver(); OverloadResolutionResults 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"; return results.getResultingCall(); } @@ -242,6 +240,7 @@ public class ControlStructureTypingUtils { }; } + @NotNull /*package*/ static TracingStrategy createTracingForSpecialConstruction( final @NotNull Call call, final @NotNull String constructionName