To green test: inheritance.jet

This commit is contained in:
Maxim Shafirov
2011-05-03 15:20:02 +04:00
parent a265c364a3
commit fe36a55a94
7 changed files with 42 additions and 43 deletions
@@ -84,37 +84,26 @@ public class ClassCodegen {
private String getSuperClass(JetClass aClass, OwnerKind kind) { private String getSuperClass(JetClass aClass, OwnerKind kind) {
List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers(); List<JetDelegationSpecifier> delegationSpecifiers = aClass.getDelegationSpecifiers();
String superClassName = null;
Set<ClassDescriptor> superInterfaces = new LinkedHashSet<ClassDescriptor>(); if (delegationSpecifiers.isEmpty()) return "java/lang/Object";
for (JetDelegationSpecifier specifier : delegationSpecifiers) {
JetType superType = bindingContext.resolveTypeReference(specifier.getTypeReference()); JetDelegationSpecifier first = delegationSpecifiers.get(0);
if (first instanceof JetDelegatorToSuperClass) {
JetType superType = bindingContext.resolveTypeReference(first.getTypeReference());
ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor(); ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
PsiElement superPsi = bindingContext.getDeclarationPsiElement(superClassDescriptor); PsiElement superPsi = bindingContext.getDeclarationPsiElement(superClassDescriptor);
if (superPsi instanceof PsiClass) { if (superPsi instanceof PsiClass) {
PsiClass psiClass = (PsiClass) superPsi; PsiClass psiClass = (PsiClass) superPsi;
String fqn = psiClass.getQualifiedName(); String fqn = psiClass.getQualifiedName();
if (!psiClass.isInterface()) { if (!psiClass.isInterface()) {
if (superClassName == null) { return fqn.replace('.', '/');
superClassName = fqn.replace('.', '/');
}
else {
throw new RuntimeException("Cannot determine single class to inherit from");
}
} }
} }
else {
superInterfaces.add(superClassDescriptor);
}
} }
else if (first instanceof JetDelegatorToSuperCall) {
if (superClassName != null) { JetType superType = bindingContext.resolveTypeReference(first.getTypeReference());
return superClassName; ClassDescriptor superClassDescriptor = (ClassDescriptor) superType.getConstructor().getDeclarationDescriptor();
} return JetTypeMapper.jvmName(superClassDescriptor, kind);
if (superInterfaces.size() > 0) {
ClassDescriptor first = superInterfaces.iterator().next();
return kind == OwnerKind.IMPLEMENTATION ? JetTypeMapper.jvmNameForImplementation(first) : JetTypeMapper.jvmNameForDelegatingImplementation(first);
} }
return "java/lang/Object"; return "java/lang/Object";
@@ -259,7 +248,7 @@ public class ClassCodegen {
JetClass superClass = (JetClass) bindingContext.getDeclarationPsiElement(superClassDescriptor); JetClass superClass = (JetClass) bindingContext.getDeclarationPsiElement(superClassDescriptor);
generateDelegates(aClass, superClass, v, generateDelegates(aClass, superClass, v,
new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false), new OwnerKind.DelegateKind(StackValue.field(fieldType, classname, delegateField, false),
JetTypeMapper.jvmNameForInterface(superClassDescriptor))); JetTypeMapper.jvmNameForInterface(superClassDescriptor)));
} }
n++; n++;
@@ -482,7 +482,6 @@ public class ExpressionCodegen extends JetVisitor {
public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean directToField) { public StackValue intermediateValueForProperty(PropertyDescriptor propertyDescriptor, final boolean directToField) {
boolean isStatic = propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor; boolean isStatic = propertyDescriptor.getContainingDeclaration() instanceof NamespaceDescriptor;
String owner = JetTypeMapper.getOwner(propertyDescriptor);
final JetType outType = propertyDescriptor.getOutType(); final JetType outType = propertyDescriptor.getOutType();
boolean isInsideClass = propertyDescriptor.getContainingDeclaration() == contextType; boolean isInsideClass = propertyDescriptor.getContainingDeclaration() == contextType;
Method getter; Method getter;
@@ -495,7 +494,18 @@ public class ExpressionCodegen extends JetVisitor {
getter = isInsideClass && propertyDescriptor.getGetter() == null ? null : typeMapper.mapGetterSignature(propertyDescriptor); getter = isInsideClass && propertyDescriptor.getGetter() == null ? null : typeMapper.mapGetterSignature(propertyDescriptor);
setter = isInsideClass && propertyDescriptor.getSetter() == null ? null : typeMapper.mapSetterSignature(propertyDescriptor); setter = isInsideClass && propertyDescriptor.getSetter() == null ? null : typeMapper.mapSetterSignature(propertyDescriptor);
} }
return StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(outType), isStatic, getter, setter);
String fieldOwner;
String interfaceOwner;
if (isInsideClass || isStatic) {
fieldOwner = interfaceOwner = JetTypeMapper.getOwner(propertyDescriptor, contextKind);
}
else {
fieldOwner = null;
interfaceOwner = JetTypeMapper.getOwner(propertyDescriptor, OwnerKind.INTERFACE);
}
return StackValue.property(propertyDescriptor.getName(), fieldOwner, interfaceOwner, typeMapper.mapType(outType), isStatic, getter, setter);
} }
@Nullable @Nullable
@@ -83,14 +83,14 @@ public class JetTypeMapper {
return jvmNameForInterface(descriptor) + "$$DImpl"; return jvmNameForInterface(descriptor) + "$$DImpl";
} }
static String getOwner(DeclarationDescriptor descriptor) { static String getOwner(DeclarationDescriptor descriptor, OwnerKind kind) {
String owner; String owner;
if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor) { if (descriptor.getContainingDeclaration() instanceof NamespaceDescriptor) {
owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration()); owner = jvmName((NamespaceDescriptor) descriptor.getContainingDeclaration());
} }
else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) { else if (descriptor.getContainingDeclaration() instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration(); ClassDescriptor classDescriptor = (ClassDescriptor) descriptor.getContainingDeclaration();
owner = jvmNameForImplementation(classDescriptor); owner = jvmName(classDescriptor, kind instanceof OwnerKind.DelegateKind ? OwnerKind.INTERFACE : kind);
} }
else { else {
throw new UnsupportedOperationException("don't know how to generate owner for parent " + descriptor.getContainingDeclaration()); throw new UnsupportedOperationException("don't know how to generate owner for parent " + descriptor.getContainingDeclaration());
@@ -35,7 +35,7 @@ public class PropertyCodegen {
throw new UnsupportedOperationException("expect a property to have a property descriptor"); throw new UnsupportedOperationException("expect a property to have a property descriptor");
} }
final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor; final PropertyDescriptor propertyDescriptor = (PropertyDescriptor) descriptor;
if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION) { if (kind == OwnerKind.NAMESPACE || kind == OwnerKind.IMPLEMENTATION || kind == OwnerKind.DELEGATING_IMPLEMENTATION) {
generateBackingField(p, kind, propertyDescriptor); generateBackingField(p, kind, propertyDescriptor);
generateGetter(p, kind, propertyDescriptor); generateGetter(p, kind, propertyDescriptor);
generateSetter(p, kind, propertyDescriptor); generateSetter(p, kind, propertyDescriptor);
@@ -150,7 +150,7 @@ public class PropertyCodegen {
} }
else { else {
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD, iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.GETSTATIC : Opcodes.GETFIELD,
JetTypeMapper.getOwner(propertyDescriptor), propertyDescriptor.getName(), JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
type.getDescriptor()); type.getDescriptor());
} }
iv.areturn(type); iv.areturn(type);
@@ -188,7 +188,7 @@ public class PropertyCodegen {
} }
//TODO: kind inst Delegate //TODO: kind inst Delegate
iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD,
JetTypeMapper.getOwner(propertyDescriptor), propertyDescriptor.getName(), JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(),
type.getDescriptor()); type.getDescriptor());
iv.visitInsn(Opcodes.RETURN); iv.visitInsn(Opcodes.RETURN);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
@@ -71,8 +71,8 @@ public abstract class StackValue {
return new Field(type, owner, name, isStatic); return new Field(type, owner, name, isStatic);
} }
public static StackValue property(String name, String owner, Type type, boolean isStatic, Method getter, Method setter) { public static StackValue property(String name, String fieldOwner, String interfaceOwner, Type type, boolean isStatic, Method getter, Method setter) {
return new Property(name, owner, getter, setter, isStatic, type); return new Property(name, fieldOwner, interfaceOwner, getter, setter, isStatic, type);
} }
private static void box(final Type type, InstructionAdapter v) { private static void box(final Type type, InstructionAdapter v) {
@@ -388,15 +388,17 @@ public abstract class StackValue {
private static class Property extends StackValue { private static class Property extends StackValue {
private final String name; private final String name;
private final String owner;
private final Method getter; private final Method getter;
private final Method setter; private final Method setter;
private final boolean isStatic; private final boolean isStatic;
private final String fieldOwner;
private final String interfaceOwner;
public Property(String name, String owner, Method getter, Method setter, boolean aStatic, Type type) { public Property(String name, String fieldOwner, String interfaceOwner, Method getter, Method setter, boolean aStatic, Type type) {
super(type); super(type);
this.name = name; this.name = name;
this.owner = owner; this.fieldOwner = fieldOwner;
this.interfaceOwner = interfaceOwner;
this.getter = getter; this.getter = getter;
this.setter = setter; this.setter = setter;
isStatic = aStatic; isStatic = aStatic;
@@ -405,20 +407,20 @@ public abstract class StackValue {
@Override @Override
public void put(Type type, InstructionAdapter v) { public void put(Type type, InstructionAdapter v) {
if (getter == null) { if (getter == null) {
v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, owner, name, type.getDescriptor()); v.visitFieldInsn(isStatic ? Opcodes.GETSTATIC : Opcodes.GETFIELD, fieldOwner, name, type.getDescriptor());
} }
else { else {
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, owner, getter.getName(), getter.getDescriptor()); v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : fieldOwner == null ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, interfaceOwner, getter.getName(), getter.getDescriptor());
} }
} }
@Override @Override
public void store(InstructionAdapter v) { public void store(InstructionAdapter v) {
if (setter == null) { if (setter == null) {
v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, owner, name, type.getDescriptor()); v.visitFieldInsn(isStatic ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, fieldOwner, name, type.getDescriptor());
} }
else { else {
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : Opcodes.INVOKEVIRTUAL, owner, setter.getName(), setter.getDescriptor()); v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : fieldOwner == null ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, interfaceOwner, setter.getName(), setter.getDescriptor());
} }
} }
} }
+1 -3
View File
@@ -18,8 +18,6 @@ fun box() : String {
if (p.x + p.y != 239) return "FAIL #3" if (p.x + p.y != 239) return "FAIL #3"
val y = new Y(-1) val y = new Y(-1)
/*
val p1 = new P1(240, y) val p1 = new P1(240, y)
if (p1.x + p1.y != 239) return "FAIL #4" if (p1.x + p1.y != 239) return "FAIL #4"
val p2 = new P2(240, y) val p2 = new P2(240, y)
@@ -30,6 +28,6 @@ fun box() : String {
val p4 = new P4(240, y) val p4 = new P4(240, y)
if (p4.x + p4.y != 239) return "FAIL #7" if (p4.x + p4.y != 239) return "FAIL #7"
*/
"OK" "OK"
} }
@@ -24,7 +24,7 @@ public class ClassGenTest extends CodegenTestCase {
checkInterface(aClass, List.class); checkInterface(aClass, List.class);
} }
public void testArrayInheritance() throws Exception { public void testInheritanceAndDelegation_DelegatingDefaultConstructorProperties() throws Exception {
loadFile("inheritance.jet"); loadFile("inheritance.jet");
System.out.println(generateToText()); System.out.println(generateToText());