fixed: explicit receiver kind for resolved call shouldn't be used as expected receiver kind for function

This commit is contained in:
Svetlana Isakova
2013-12-10 13:46:23 +04:00
parent 928f77ffce
commit 656cc16a81
@@ -75,8 +75,6 @@ import static org.jetbrains.jet.codegen.FunctionTypesUtil.getFunctionImplType;
import static org.jetbrains.jet.codegen.binding.CodegenBinding.*; import static org.jetbrains.jet.codegen.binding.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.*; import static org.jetbrains.jet.lang.resolve.BindingContext.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull; import static org.jetbrains.jet.lang.resolve.BindingContextUtils.getNotNull;
import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.RECEIVER_ARGUMENT;
import static org.jetbrains.jet.lang.resolve.calls.tasks.ExplicitReceiverKind.THIS_OBJECT;
import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*; import static org.jetbrains.jet.lang.resolve.java.AsmTypeConstants.*;
import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER; import static org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverValue.NO_RECEIVER;
@@ -2487,20 +2485,21 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction); JetCallExpression fakeExpression = constructFakeFunctionCall(referencedFunction);
final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments(); final List<? extends ValueArgument> fakeArguments = fakeExpression.getValueArguments();
final ReceiverValue receiverValue = computeAndSaveReceiver(signature, codegen); final ReceiverValue thisObject = computeAndSaveReceiver(signature, codegen, referencedFunction.getExpectedThisObject());
final ReceiverValue extensionReceiver = computeAndSaveReceiver(signature, codegen, referencedFunction.getReceiverParameter());
computeAndSaveArguments(codegen.myFrameMap, fakeArguments, codegen); computeAndSaveArguments(codegen.myFrameMap, fakeArguments, codegen);
ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) { ResolvedCall<CallableDescriptor> fakeResolvedCall = new DelegatingResolvedCall<CallableDescriptor>(resolvedCall) {
@NotNull @NotNull
@Override @Override
public ReceiverValue getReceiverArgument() { public ReceiverValue getReceiverArgument() {
return resolvedCall.getExplicitReceiverKind() == RECEIVER_ARGUMENT ? receiverValue : NO_RECEIVER; return extensionReceiver;
} }
@NotNull @NotNull
@Override @Override
public ReceiverValue getThisObject() { public ReceiverValue getThisObject() {
return resolvedCall.getExplicitReceiverKind() == THIS_OBJECT ? receiverValue : NO_RECEIVER; return thisObject;
} }
@NotNull @NotNull
@@ -2565,19 +2564,12 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
} }
@NotNull @NotNull
private ReceiverValue computeAndSaveReceiver(@NotNull JvmMethodSignature signature, @NotNull ExpressionCodegen codegen) { private ReceiverValue computeAndSaveReceiver(
CallableDescriptor referencedFunction = resolvedCall.getCandidateDescriptor(); @NotNull JvmMethodSignature signature,
@NotNull ExpressionCodegen codegen,
ReceiverParameterDescriptor receiverParameter = referencedFunction.getReceiverParameter(); @Nullable ReceiverParameterDescriptor receiver
ReceiverParameterDescriptor expectedThisObject = referencedFunction.getExpectedThisObject(); ) {
assert receiverParameter == null || expectedThisObject == null : if (receiver == null) return NO_RECEIVER;
"Extensions in classes can't be referenced via callable reference expressions: " + referencedFunction;
ReceiverParameterDescriptor receiver = receiverParameter != null ? receiverParameter : expectedThisObject;
if (receiver == null) {
return NO_RECEIVER;
}
JetExpression receiverExpression = JetPsiFactory.createExpression(state.getProject(), "callableReferenceFakeReceiver"); JetExpression receiverExpression = JetPsiFactory.createExpression(state.getProject(), "callableReferenceFakeReceiver");