correct generation of 'this' in DImpl classes
This commit is contained in:
@@ -1346,11 +1346,9 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
}
|
||||
|
||||
private void pushOuterClassArguments(ClassDescriptor classDecl) {
|
||||
final List<ClassDescriptor> 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));
|
||||
}
|
||||
|
||||
@@ -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, "<init>", /* 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();
|
||||
}
|
||||
|
||||
@@ -253,8 +253,9 @@ public class JetTypeMapper {
|
||||
List<ValueParameterDescriptor> parameters = descriptor.getUnsubstitutedValueParameters();
|
||||
List<Type> parameterTypes = new ArrayList<Type>();
|
||||
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("<init>", Type.VOID_TYPE, parameterTypes.toArray(new Type[parameterTypes.size()]));
|
||||
}
|
||||
|
||||
public static List<ClassDescriptor> getOuterClassDescriptors(ClassDescriptor classDescriptor) {
|
||||
List<ClassDescriptor> result = new ArrayList<ClassDescriptor>();
|
||||
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)) {
|
||||
|
||||
@@ -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 + ")";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
import java.util.*
|
||||
import java.io.*
|
||||
|
||||
class World() {
|
||||
public val items: ArrayList<Item> = new ArrayList<Item>
|
||||
|
||||
class Item() {
|
||||
{
|
||||
items.add(this)
|
||||
}
|
||||
}
|
||||
|
||||
val foo = new Item()
|
||||
}
|
||||
|
||||
fun box() {
|
||||
val w = new World()
|
||||
if (w.items.size() != 1) return "fail"
|
||||
return "OK"
|
||||
}
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user