Fix for KT-3335: Creating imported super class' inner class fails in codegen

#KT-3335 Fixed
This commit is contained in:
Michael Bogdanov
2015-10-30 16:48:51 +03:00
parent 3bd7f87d2b
commit 65b85711e3
7 changed files with 177 additions and 6 deletions
@@ -2562,7 +2562,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
@NotNull
public StackValue generateReceiverValue(@NotNull ReceiverValue receiverValue) {
public StackValue generateReceiverValue(@NotNull ReceiverValue receiverValue, boolean isSuper) {
if (receiverValue instanceof ClassReceiver) {
ClassDescriptor receiverDescriptor = ((ClassReceiver) receiverValue).getDeclarationDescriptor();
if (DescriptorUtils.isCompanionObject(receiverDescriptor)) {
@@ -2575,7 +2575,7 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
}
}
else {
return StackValue.thisOrOuter(this, receiverDescriptor, false, isEnumEntry(receiverDescriptor));
return StackValue.thisOrOuter(this, receiverDescriptor, isSuper, isEnumEntry(receiverDescriptor));
}
}
else if (receiverValue instanceof ScriptReceiver) {
@@ -3437,14 +3437,20 @@ public class ExpressionCodegen extends KtVisitor<StackValue, StackValue> impleme
ConstructorDescriptor constructor = getConstructorDescriptor(resolvedCall);
ReceiverParameterDescriptor dispatchReceiver = constructor.getDispatchReceiverParameter();
ClassDescriptor containingDeclaration = constructor.getContainingDeclaration();
if (dispatchReceiver != null) {
Type receiverType = typeMapper.mapType(dispatchReceiver.getType());
generateReceiverValue(resolvedCall.getDispatchReceiver()).put(receiverType, v);
ReceiverValue receiver = resolvedCall.getDispatchReceiver();
boolean callSuper = containingDeclaration.isInner() &&
receiver instanceof ClassReceiver &&
((ClassReceiver) receiver).getDeclarationDescriptor().getOriginal() !=
containingDeclaration.getOriginal();
generateReceiverValue(receiver, callSuper).put(receiverType, v);
}
// Resolved call to local class constructor doesn't have dispatchReceiver, so we need to generate closure on stack
// See StackValue.receiver for more info
pushClosureOnStack(constructor.getContainingDeclaration(), dispatchReceiver == null, defaultCallGenerator);
pushClosureOnStack(containingDeclaration, dispatchReceiver == null, defaultCallGenerator);
constructor = SamCodegenUtil.resolveSamAdapter(constructor);
CallableMethod method = typeMapper.mapToCallableMethod(constructor, false);
@@ -535,7 +535,7 @@ public abstract class StackValue {
) {
if (receiver == none()) {
if (receiverValue.exists()) {
return codegen.generateReceiverValue(receiverValue);
return codegen.generateReceiverValue(receiverValue, false);
}
else if (isLocalFunCall(callableMethod) && !isExtension) {
StackValue value = codegen.findLocalOrCapturedValue(resolvedCall.getResultingDescriptor().getOriginal());
@@ -862,7 +862,7 @@ public abstract class StackValue {
if (resolvedSetCall.getDispatchReceiver().exists()) {
if (resolvedSetCall.getExtensionReceiver().exists()) {
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver()).put(OBJECT_TYPE, v);
codegen.generateReceiverValue(resolvedSetCall.getDispatchReceiver(), false).put(OBJECT_TYPE, v);
}
v.load(realReceiverIndex, realReceiverType);
}