pass outer instance when calling base inner class constructor in inner class

This commit is contained in:
Dmitry Jemerov
2011-05-30 19:55:44 +04:00
parent 8adaf297ef
commit e616c38a9f
4 changed files with 36 additions and 9 deletions
@@ -767,13 +767,17 @@ public class ExpressionCodegen extends JetVisitor {
}
}
else if (!(expression.getParent() instanceof JetSafeQualifiedExpression)) {
v.load(0, JetTypeMapper.TYPE_OBJECT); // TODO hope it works; really need more checks here :)
if (calleeContainingClass != null && contextType instanceof ClassDescriptor &&
calleeContainingClass == contextType.getContainingDeclaration()) {
v.getfield(typeMapper.jvmName((ClassDescriptor) contextType, OwnerKind.IMPLEMENTATION),
"this$0", typeMapper.jvmType(calleeContainingClass, OwnerKind.INTERFACE).getDescriptor());
// TODO handle more levels of class nestng
}
generateThisOrOuter(calleeContainingClass);
}
}
public void generateThisOrOuter(ClassDescriptor calleeContainingClass) {
v.load(0, JetTypeMapper.TYPE_OBJECT); // TODO hope it works; really need more checks here :)
if (calleeContainingClass != null && contextType instanceof ClassDescriptor &&
calleeContainingClass == contextType.getContainingDeclaration()) {
v.getfield(typeMapper.jvmName((ClassDescriptor) contextType, OwnerKind.IMPLEMENTATION),
"this$0", typeMapper.jvmType(calleeContainingClass, OwnerKind.IMPLEMENTATION).getDescriptor());
// TODO handle more levels of class nestng
}
}
@@ -112,7 +112,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
final DeclarationDescriptor outerDescriptor = descriptor.getContainingDeclaration();
if (outerDescriptor instanceof ClassDescriptor) {
final ClassDescriptor outerClassDescriptor = (ClassDescriptor) outerDescriptor;
final Type type = JetTypeMapper.jetInterfaceType(outerClassDescriptor);
final Type type = JetTypeMapper.jetImplementationType(outerClassDescriptor);
String interfaceDesc = type.getDescriptor();
final String fieldName = "this$0";
v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null);
@@ -187,6 +187,11 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
iv.dup();
}
if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) {
iv.load(1, typeMapper.jvmType((ClassDescriptor) descriptor.getContainingDeclaration(), OwnerKind.IMPLEMENTATION));
// TODO handle classes further out
}
Method method1 = typeMapper.mapConstructorSignature(constructorDescriptor1, kind);
final Type[] argTypes1 = method1.getArgumentTypes();
List<JetArgument> args = superCall.getValueArguments();
@@ -195,7 +200,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
codegen.gen(arg.getArgumentExpression(), argTypes1[i]);
}
iv.invokespecial(type.getClassName(), "<init>", method1.getDescriptor());
iv.invokespecial(type.getInternalName(), "<init>", method1.getDescriptor());
}
else if (specifier instanceof JetDelegatorByExpressionSpecifier) {
codegen.genToJVMStack(((JetDelegatorByExpressionSpecifier) specifier).getDelegateExpression());
@@ -0,0 +1,14 @@
class Outer() {
class InnerBase() {
}
class InnerDerived(): InnerBase() {
}
public val foo: InnerBase? = new InnerDerived()
}
fun box() {
val o = new Outer()
return if (o.foo === null) "fail" else "OK"
}
@@ -61,6 +61,10 @@ public class ClassGenTest extends CodegenTestCase {
blackBoxFile("classes/innerClass.jet");
}
public void testInheritedInnerClass() throws Exception {
blackBoxFile("classes/inheritedInnerClass.jet");
}
public void testInitializerBlock() throws Exception {
blackBoxFile("classes/initializerBlock.jet");
}