diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 776498d560a..7f8234c22e1 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1346,11 +1346,9 @@ public class ExpressionCodegen extends JetVisitor { } private void pushOuterClassArguments(ClassDescriptor classDecl) { - final List outerClassDescriptors = JetTypeMapper.getOuterClassDescriptors(classDecl); - if (outerClassDescriptors.size() > 0) { + if (classDecl.getContainingDeclaration() instanceof ClassDescriptor) { v.load(0, JetTypeMapper.jetImplementationType(classDecl)); } - // TODO push further outer classes } private Type generateJavaConstructorCall(JetNewExpression expression, PsiMethod constructor) { @@ -1426,12 +1424,14 @@ public class ExpressionCodegen extends JetVisitor { } else { ClassDescriptor contextClass = (ClassDescriptor) contextType; + final Type thisType = typeMapper.jvmType(contextClass, contextKind); if (contextKind == OwnerKind.IMPLEMENTATION) { - myStack.push(StackValue.local(0, JetTypeMapper.jetImplementationType(contextClass))); + myStack.push(StackValue.local(0, thisType)); } else if (contextKind == OwnerKind.DELEGATING_IMPLEMENTATION) { + v.load(0, thisType); myStack.push(StackValue.field(JetTypeMapper.jetInterfaceType(contextClass), - typeMapper.jvmName(contextClass, contextKind), + thisType.getInternalName(), "$this", false)); } diff --git a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java index 43e7a429096..8304d18d9e2 100644 --- a/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ImplementationBodyCodegen.java @@ -61,7 +61,12 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { generateStaticInitializer(); - generatePrimaryConstructor(); + try { + generatePrimaryConstructor(); + } + catch(RuntimeException e) { + throw new RuntimeException("Error generating primary constructor of class " + myClass.getName() + " with kind " + kind, e); + } generateGetTypeInfo(); } @@ -103,23 +108,26 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { iv.invokespecial(superClass, "", /* TODO super constructor descriptor */"()V"); } - int index = 0; - for (ClassDescriptor outerClassDescriptor : JetTypeMapper.getOuterClassDescriptors(descriptor)) { + int index = 1; // this + final DeclarationDescriptor outerDescriptor = descriptor.getContainingDeclaration(); + if (outerDescriptor instanceof ClassDescriptor) { + final ClassDescriptor outerClassDescriptor = (ClassDescriptor) outerDescriptor; final Type type = JetTypeMapper.jetInterfaceType(outerClassDescriptor); String interfaceDesc = type.getDescriptor(); - final String fieldName = "this$" + index; + final String fieldName = "this$0"; v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, fieldName, interfaceDesc, null, null); iv.load(0, classType); - iv.load(index + 1, type); + iv.load(index, type); iv.putfield(classname, fieldName, interfaceDesc); frameMap.enterTemp(); + index++; } if (kind == OwnerKind.DELEGATING_IMPLEMENTATION) { String interfaceDesc = JetTypeMapper.jetInterfaceType(descriptor).getDescriptor(); v.visitField(Opcodes.ACC_PRIVATE | Opcodes.ACC_FINAL, "$this", interfaceDesc, /*TODO*/null, null); iv.load(0, classType); - iv.load(1, argTypes[0]); + iv.load(index, argTypes[0]); iv.putfield(classname, "$this", interfaceDesc); frameMap.enterTemp(); } diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index 38f8f828a31..2e1c58c79c9 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -253,8 +253,9 @@ public class JetTypeMapper { List parameters = descriptor.getUnsubstitutedValueParameters(); List parameterTypes = new ArrayList(); ClassDescriptor classDescriptor = descriptor.getContainingDeclaration(); - for (ClassDescriptor outerDescriptor : getOuterClassDescriptors(classDescriptor)) { - parameterTypes.add(jvmType(outerDescriptor, OwnerKind.IMPLEMENTATION)); + final DeclarationDescriptor outerDescriptor = classDescriptor.getContainingDeclaration(); + if (outerDescriptor instanceof ClassDescriptor) { + parameterTypes.add(jvmType((ClassDescriptor) outerDescriptor, OwnerKind.IMPLEMENTATION)); } if (delegate) { parameterTypes.add(jetInterfaceType(classDescriptor)); @@ -271,16 +272,6 @@ public class JetTypeMapper { return new Method("", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()])); } - public static List getOuterClassDescriptors(ClassDescriptor classDescriptor) { - List result = new ArrayList(); - DeclarationDescriptor outerClass = classDescriptor.getContainingDeclaration(); - while (outerClass instanceof ClassDescriptor) { - result.add((ClassDescriptor) outerClass); - outerClass = outerClass.getContainingDeclaration(); - } - return result; - } - static int getAccessModifiers(JetDeclaration p, int defaultFlags) { int flags = 0; if (p.hasModifier(JetTokens.PUBLIC_KEYWORD)) { diff --git a/idea/src/org/jetbrains/jet/codegen/OwnerKind.java b/idea/src/org/jetbrains/jet/codegen/OwnerKind.java index 3f183132f1a..55c71dde735 100644 --- a/idea/src/org/jetbrains/jet/codegen/OwnerKind.java +++ b/idea/src/org/jetbrains/jet/codegen/OwnerKind.java @@ -1,21 +1,26 @@ package org.jetbrains.jet.codegen; -import org.objectweb.asm.Type; - /** * @author max */ public class OwnerKind { - public static final OwnerKind NAMESPACE = new OwnerKind(); - public static final OwnerKind INTERFACE = new OwnerKind(); - public static final OwnerKind IMPLEMENTATION = new OwnerKind(); - public static final OwnerKind DELEGATING_IMPLEMENTATION = new OwnerKind(); + private final String name; + + public OwnerKind(String name) { + this.name = name; + } + + public static final OwnerKind NAMESPACE = new OwnerKind("namespace"); + public static final OwnerKind INTERFACE = new OwnerKind("interface"); + public static final OwnerKind IMPLEMENTATION = new OwnerKind("implementation"); + public static final OwnerKind DELEGATING_IMPLEMENTATION = new OwnerKind("delegating implementation"); public static class DelegateKind extends OwnerKind { private final StackValue delegate; private final String ownerClass; public DelegateKind(StackValue delegate, String ownerClass) { + super("delegateKind"); this.delegate = delegate; this.ownerClass = ownerClass; } @@ -28,4 +33,9 @@ public class OwnerKind { return ownerClass; } } + + @Override + public String toString() { + return "OwnerKind(" + name + ")"; + } } diff --git a/idea/testData/codegen/classes/initializerBlockDImpl.jet b/idea/testData/codegen/classes/initializerBlockDImpl.jet new file mode 100644 index 00000000000..17272e9f75e --- /dev/null +++ b/idea/testData/codegen/classes/initializerBlockDImpl.jet @@ -0,0 +1,20 @@ +import java.util.* +import java.io.* + +class World() { + public val items: ArrayList = new ArrayList + + class Item() { + { + items.add(this) + } + } + + val foo = new Item() +} + +fun box() { + val w = new World() + if (w.items.size() != 1) return "fail" + return "OK" +} diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 0fce968a329..7d35d331ea3 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -79,4 +79,8 @@ public class ClassGenTest extends CodegenTestCase { public void testInheritedMethod() throws Exception { blackBoxFile("classes/inheritedMethod.jet"); } + + public void testInitializerBlockDImpl() throws Exception { + blackBoxFile("classes/initializerBlockDImpl.jet"); + } }