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 f30e26fdad2..739652befb0 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 @@ -253,7 +253,8 @@ public class CallResolver { return checkArgumentTypesAndFail(context); } Collection> candidates = - TaskPrioritizer.convertWithImpliedThisAndNoReceiver(context.scope, constructors); + TaskPrioritizer.convertWithImpliedThisAndNoReceiver( + context.scope, constructors, context.call); prioritizedTasks = TaskPrioritizer.computePrioritizedTasksFromCandidates( context, candidates, TracingStrategyImpl.create(functionReference, context.call)); } @@ -276,7 +277,8 @@ public class CallResolver { context.trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); return checkArgumentTypesAndFail(context); } - List> candidates = ResolutionCandidate.convertCollection(constructors, JetPsiUtil.isSafeCall(context.call)); + List> candidates = ResolutionCandidate.convertCollection( + context.call, constructors, JetPsiUtil.isSafeCall(context.call)); prioritizedTasks = Collections.singletonList(new ResolutionTask(candidates, functionReference, context)); // !! DataFlowInfo.EMPTY } else if (calleeExpression != null) { 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 e9090c61c4c..03d80116c1e 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 @@ -114,7 +114,8 @@ public class CallTransformer { candidate, variableCall, candidateTrace, task); ResolutionCandidate candidateWithoutReceiver = ResolutionCandidate.create( - candidate.getDescriptor(), candidate.getThisObject(), ReceiverValue.NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, false); + candidate.getCall(), candidate.getDescriptor(), candidate.getThisObject(), ReceiverValue.NO_RECEIVER, + ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, false); CallCandidateResolutionContext contextWithoutReceiver = createContextWithChainedTrace( candidateWithoutReceiver, variableCallWithoutReceiver, candidateTrace, task); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/DelegatingResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/DelegatingResolvedCall.java index bad8b99ff7e..cf0b60bafb2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/DelegatingResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/DelegatingResolvedCall.java @@ -21,6 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.JetType; @@ -35,6 +36,12 @@ public abstract class DelegatingResolvedCall imple this.resolvedCall = resolvedCall; } + @NotNull + @Override + public Call getCall() { + return resolvedCall.getCall(); + } + @NotNull @Override public D getCandidateDescriptor() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java index 5cd34844307..97f07af9104 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCall.java @@ -21,8 +21,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; -import org.jetbrains.jet.lang.psi.ValueArgument; -import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo; +import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.jet.lang.types.JetType; @@ -31,6 +30,10 @@ import java.util.List; import java.util.Map; public interface ResolvedCall { + /** The call that was resolved to this ResolvedCall */ + @NotNull + Call getCall(); + /** A target callable descriptor as it was accessible in the corresponding scope, i.e. with type arguments not substituted */ @NotNull D getCandidateDescriptor(); @@ -63,6 +66,7 @@ public interface ResolvedCall { @NotNull Map getTypeArguments(); + /** Data flow info for each argument and the result data flow info */ @NotNull DataFlowInfoForArguments getDataFlowInfoForArguments(); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java index c120afa4a51..c97098fec84 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/ResolvedCallImpl.java @@ -24,6 +24,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; +import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.ValueArgument; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; import org.jetbrains.jet.lang.resolve.calls.CallResolverUtil; @@ -69,6 +70,7 @@ public class ResolvedCallImpl implements ResolvedC return new ResolvedCallImpl(candidate, trace, tracing, dataFlowInfoForArguments); } + private final Call call; private final D candidateDescriptor; private D resultingDescriptor; // Probably substituted private final ReceiverValue thisObject; // receiver object of a method @@ -96,6 +98,7 @@ public class ResolvedCallImpl implements ResolvedC @NotNull TracingStrategy tracing, @NotNull MutableDataFlowInfoForArguments dataFlowInfoForArguments ) { + this.call = candidate.getCall(); this.candidateDescriptor = candidate.getDescriptor(); this.thisObject = candidate.getThisObject(); this.receiverArgument = candidate.getReceiverArgument(); @@ -143,6 +146,12 @@ public class ResolvedCallImpl implements ResolvedC return tracing; } + @NotNull + @Override + public Call getCall() { + return call; + } + @Override @NotNull public D getCandidateDescriptor() { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java index e02017fe167..f521e1066d8 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/calls/model/VariableAsFunctionResolvedCall.java @@ -22,6 +22,7 @@ import org.jetbrains.jet.lang.descriptors.FunctionDescriptor; import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor; import org.jetbrains.jet.lang.descriptors.ValueParameterDescriptor; import org.jetbrains.jet.lang.descriptors.VariableDescriptor; +import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.resolve.DelegatingBindingTrace; import org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind; import org.jetbrains.jet.lang.resolve.calls.results.ResolutionStatus; @@ -51,6 +52,12 @@ public class VariableAsFunctionResolvedCall implements ResolvedCallWithTrace { + private final Call call; private final D candidateDescriptor; private ReceiverValue thisObject; // receiver object of a method private ReceiverValue receiverArgument; // receiver of an extension function private ExplicitReceiverKind explicitReceiverKind; private Boolean isSafeCall; - private ResolutionCandidate(@NotNull D descriptor, @NotNull ReceiverValue thisObject, @NotNull ReceiverValue receiverArgument, - @NotNull ExplicitReceiverKind explicitReceiverKind, @Nullable Boolean isSafeCall) { + private ResolutionCandidate( + @NotNull Call call, @NotNull D descriptor, @NotNull ReceiverValue thisObject, + @NotNull ReceiverValue receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind, @Nullable Boolean isSafeCall + ) { + this.call = call; this.candidateDescriptor = descriptor; this.thisObject = thisObject; this.receiverArgument = receiverArgument; @@ -43,18 +48,22 @@ public class ResolutionCandidate { this.isSafeCall = isSafeCall; } - /*package*/ static ResolutionCandidate create(@NotNull D descriptor) { - return new ResolutionCandidate(descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null); + /*package*/ static ResolutionCandidate create(@NotNull Call call, @NotNull D descriptor) { + return new ResolutionCandidate(call, descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, null); } /* 'null' for isSafeCall parameter if it should be set later (with 'setSafeCall') */ - public static ResolutionCandidate create(@NotNull D descriptor, @Nullable Boolean isSafeCall) { - return new ResolutionCandidate(descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, isSafeCall); + public static ResolutionCandidate create( + @NotNull Call call, @NotNull D descriptor, @Nullable Boolean isSafeCall + ) { + return new ResolutionCandidate(call, descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, isSafeCall); } - public static ResolutionCandidate create(@NotNull D descriptor, @NotNull ReceiverValue thisObject, - @NotNull ReceiverValue receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind, boolean isSafeCall) { - return new ResolutionCandidate(descriptor, thisObject, receiverArgument, explicitReceiverKind, isSafeCall); + public static ResolutionCandidate create( + @NotNull Call call, @NotNull D descriptor, @NotNull ReceiverValue thisObject, + @NotNull ReceiverValue receiverArgument, @NotNull ExplicitReceiverKind explicitReceiverKind, boolean isSafeCall + ) { + return new ResolutionCandidate(call, descriptor, thisObject, receiverArgument, explicitReceiverKind, isSafeCall); } public void setThisObject(@NotNull ReceiverValue thisObject) { @@ -69,6 +78,11 @@ public class ResolutionCandidate { this.explicitReceiverKind = explicitReceiverKind; } + @NotNull + public Call getCall() { + return call; + } + @NotNull public D getDescriptor() { return candidateDescriptor; @@ -90,10 +104,12 @@ public class ResolutionCandidate { } @NotNull - public static List> convertCollection(@NotNull Collection descriptors, boolean isSafeCall) { + public static List> convertCollection( + @NotNull Call call, @NotNull Collection descriptors, boolean isSafeCall + ) { List> result = Lists.newArrayList(); for (D descriptor : descriptors) { - result.add(create(descriptor, isSafeCall)); + result.add(create(call, descriptor, isSafeCall)); } return result; } 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 22f01de015d..91cbc230255 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 @@ -23,6 +23,7 @@ import com.intellij.openapi.util.Pair; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.Call; import org.jetbrains.jet.lang.psi.JetExpression; import org.jetbrains.jet.lang.psi.JetReferenceExpression; import org.jetbrains.jet.lang.psi.JetSuperExpression; @@ -141,7 +142,7 @@ public class TaskPrioritizer { Collection membersForThisVariant = callableDescriptorCollector.getMembersByName(type, c.name, c.context.trace); convertWithReceivers(membersForThisVariant, explicitReceiver, - NO_RECEIVER, members, createKind(THIS_OBJECT, isExplicit)); + NO_RECEIVER, members, createKind(THIS_OBJECT, isExplicit), c.context.call); } c.result.addCandidates(members); } @@ -155,7 +156,7 @@ public class TaskPrioritizer { //extensions Collection> extensions = convertWithImpliedThis( c.scope, explicitReceiver, callableDescriptorCollector.getNonMembersByName(c.scope, c.name, c.context.trace), - createKind(RECEIVER_ARGUMENT, isExplicit)); + createKind(RECEIVER_ARGUMENT, isExplicit), c.context.call); c.result.addCandidates(extensions); } } @@ -174,7 +175,7 @@ public class TaskPrioritizer { Collection memberExtensions = callableDescriptorCollector.getNonMembersByName( thisObject.getType().getMemberScope(), c.name, c.context.trace); c.result.addCandidates(convertWithReceivers( - memberExtensions, thisObject, receiverParameter, receiverKind)); + memberExtensions, thisObject, receiverParameter, receiverKind, c.context.call)); } private static void addCandidatesForNoReceiver( @@ -186,7 +187,7 @@ public class TaskPrioritizer { for (CallableDescriptorCollector callableDescriptorCollector : c.callableDescriptorCollectors) { Collection> members = convertWithImpliedThisAndNoReceiver( - c.scope, callableDescriptorCollector.getNonExtensionsByName(c.scope, c.name, c.context.trace)); + c.scope, callableDescriptorCollector.getNonExtensionsByName(c.scope, c.name, c.context.trace), c.context.call); List> nonlocals = Lists.newArrayList(); List> locals = Lists.newArrayList(); @@ -261,10 +262,11 @@ public class TaskPrioritizer { @NotNull Collection descriptors, @NotNull ReceiverValue thisObject, @NotNull ReceiverValue receiverParameter, - @NotNull ExplicitReceiverKind explicitReceiverKind + @NotNull ExplicitReceiverKind explicitReceiverKind, + @NotNull Call call ) { Collection> result = Lists.newArrayList(); - convertWithReceivers(descriptors, thisObject, receiverParameter, result, explicitReceiverKind); + convertWithReceivers(descriptors, thisObject, receiverParameter, result, explicitReceiverKind, call); return result; } @@ -273,14 +275,15 @@ public class TaskPrioritizer { @NotNull ReceiverValue thisObject, @NotNull ReceiverValue receiverParameter, @NotNull Collection> result, - @NotNull ExplicitReceiverKind explicitReceiverKind + @NotNull ExplicitReceiverKind explicitReceiverKind, + @NotNull Call call ) { for (D extension : descriptors) { if (DescriptorUtils.isConstructorOfStaticNestedClass(extension)) { // We don't want static nested classes' constructors to be resolved with expectedThisObject continue; } - ResolutionCandidate candidate = ResolutionCandidate.create(extension); + ResolutionCandidate candidate = ResolutionCandidate.create(call, extension); candidate.setThisObject(thisObject); candidate.setReceiverArgument(receiverParameter); candidate.setExplicitReceiverKind(explicitReceiverKind); @@ -290,20 +293,22 @@ public class TaskPrioritizer { public static Collection> convertWithImpliedThisAndNoReceiver( @NotNull JetScope scope, - @NotNull Collection descriptors + @NotNull Collection descriptors, + @NotNull Call call ) { - return convertWithImpliedThis(scope, NO_RECEIVER, descriptors, NO_EXPLICIT_RECEIVER); + return convertWithImpliedThis(scope, NO_RECEIVER, descriptors, NO_EXPLICIT_RECEIVER, call); } public static Collection> convertWithImpliedThis( @NotNull JetScope scope, @NotNull ReceiverValue receiverParameter, @NotNull Collection descriptors, - ExplicitReceiverKind receiverKind + @NotNull ExplicitReceiverKind receiverKind, + @NotNull Call call ) { Collection> result = Lists.newArrayList(); for (D descriptor : descriptors) { - ResolutionCandidate candidate = ResolutionCandidate.create(descriptor); + ResolutionCandidate candidate = ResolutionCandidate.create(call, descriptor); candidate.setReceiverArgument(receiverParameter); candidate.setExplicitReceiverKind(receiverKind); if (setImpliedThis(scope, candidate)) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java index 7921e8abda2..4103e3b8476 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/types/expressions/BasicExpressionTypingVisitor.java @@ -411,14 +411,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { JetExpression expression ) { BindingTrace trace = context.trace; - ResolutionCandidate resolutionCandidate = - ResolutionCandidate.create(descriptor, - NO_RECEIVER, - NO_RECEIVER, - ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, - false); - Call call = CallMaker.makeCall(expression, NO_RECEIVER, null, expression, Collections.emptyList()); + ResolutionCandidate resolutionCandidate = + ResolutionCandidate.create( + call, descriptor, NO_RECEIVER, NO_RECEIVER, ExplicitReceiverKind.NO_EXPLICIT_RECEIVER, false); + ResolvedCallImpl resolvedCall = ResolvedCallImpl.create(resolutionCandidate, TemporaryBindingTrace.create(trace, "Fake trace for fake 'this' or 'super' resolved call"), 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 37bc85a7a8d..6dd1291eaf5 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 @@ -73,7 +73,7 @@ public class ControlStructureTypingUtils { SimpleFunctionDescriptorImpl function = createFunctionDescriptorForSpecialConstruction( constructionName.toUpperCase(), argumentNames, isArgumentNullable); TracingStrategy tracing = createTracingForSpecialConstruction(call, constructionName); - ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(function, null); + ResolutionCandidate resolutionCandidate = ResolutionCandidate.create(call, function, null); CallResolver callResolver = expressionTypingServices.getCallResolver(); OverloadResolutionResults results = callResolver.resolveCallWithKnownCandidate( call, tracing, context, resolutionCandidate, dataFlowInfoForArguments);