From fe36a55a9435f3074492dd7a005ecc8ead4bba8d Mon Sep 17 00:00:00 2001 From: Maxim Shafirov Date: Tue, 3 May 2011 15:20:02 +0400 Subject: [PATCH] To green test: inheritance.jet --- .../jetbrains/jet/codegen/ClassCodegen.java | 35 +++++++------------ .../jet/codegen/ExpressionCodegen.java | 14 ++++++-- .../jetbrains/jet/codegen/JetTypeMapper.java | 4 +-- .../jet/codegen/PropertyCodegen.java | 6 ++-- .../org/jetbrains/jet/codegen/StackValue.java | 20 ++++++----- idea/testData/codegen/inheritance.jet | 4 +-- .../jetbrains/jet/codegen/ClassGenTest.java | 2 +- 7 files changed, 42 insertions(+), 43 deletions(-) diff --git a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java index a7e4872dff8..1a7ca37c192 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -84,37 +84,26 @@ public class ClassCodegen { private String getSuperClass(JetClass aClass, OwnerKind kind) { List delegationSpecifiers = aClass.getDelegationSpecifiers(); - String superClassName = null; - Set superInterfaces = new LinkedHashSet(); - 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++; diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index ea00ced7f68..497702e2f5e 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -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 diff --git a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java index eb6e313936b..a0e910bf3bf 100644 --- a/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java +++ b/idea/src/org/jetbrains/jet/codegen/JetTypeMapper.java @@ -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()); diff --git a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java index fec3d046adc..49feb38c91f 100644 --- a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -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); diff --git a/idea/src/org/jetbrains/jet/codegen/StackValue.java b/idea/src/org/jetbrains/jet/codegen/StackValue.java index dc33d4e9daa..818986d7a4e 100644 --- a/idea/src/org/jetbrains/jet/codegen/StackValue.java +++ b/idea/src/org/jetbrains/jet/codegen/StackValue.java @@ -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()); } } } diff --git a/idea/testData/codegen/inheritance.jet b/idea/testData/codegen/inheritance.jet index 2fc3caace24..56514a2b9c4 100644 --- a/idea/testData/codegen/inheritance.jet +++ b/idea/testData/codegen/inheritance.jet @@ -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" } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java index 7a07d129fa2..6999f3e3b13 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -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());