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