diff --git a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java index 49feb38c91f..06c2b490908 100644 --- a/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/PropertyCodegen.java @@ -58,6 +58,12 @@ public class PropertyCodegen { null, null); } } + else if (kind instanceof OwnerKind.DelegateKind) { + generateDefaultGetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind); + if (propertyDescriptor.isVar()) { + generateDefaultSetter(propertyDescriptor, Opcodes.ACC_PUBLIC, kind); + } + } } private void generateBackingField(JetProperty p, OwnerKind kind, PropertyDescriptor propertyDescriptor) { @@ -179,17 +185,27 @@ public class PropertyCodegen { mv.visitCode(); InstructionAdapter iv = new InstructionAdapter(mv); final Type type = mapper.mapType(propertyDescriptor.getOutType()); + int paramCode = 0; if (kind != OwnerKind.NAMESPACE) { iv.load(0, JetTypeMapper.TYPE_OBJECT); - iv.load(1, type); + paramCode = 1; + } + + if (kind instanceof OwnerKind.DelegateKind) { + OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind; + iv.load(0, JetTypeMapper.TYPE_OBJECT); + dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv); + + iv.load(paramCode, type); + iv.invokeinterface(dk.getOwnerClass(), setterName(propertyDescriptor.getName()), signature); } else { - iv.load(0, type); + iv.load(paramCode, type); + iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, + JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(), + type.getDescriptor()); } - //TODO: kind inst Delegate - iv.visitFieldInsn(kind == OwnerKind.NAMESPACE ? Opcodes.PUTSTATIC : Opcodes.PUTFIELD, - JetTypeMapper.getOwner(propertyDescriptor, kind), propertyDescriptor.getName(), - type.getDescriptor()); + iv.visitInsn(Opcodes.RETURN); mv.visitMaxs(0, 0); mv.visitEnd(); diff --git a/idea/testData/codegen/propertyDelegation.jet b/idea/testData/codegen/propertyDelegation.jet new file mode 100644 index 00000000000..fa962d08682 --- /dev/null +++ b/idea/testData/codegen/propertyDelegation.jet @@ -0,0 +1,33 @@ +class Base() { + public val plain = 239 + public val read : Int + get() = 239 + + public var readwrite : Int + get() = $readwrite + 1 + set(n : Int) { + $readwrite = n + } +} + +class Abstract {} + +class Derived1() : Base(), Abstract {} +class Derived2() : Abstract, Base() {} + +fun code(s : Base) : Int { + if (s.plain != 239) return 1 + if (s.read != 239) return 2 + s.readwrite = 238 + if (s.readwrite != 239) return 3 + return 0 +} + +fun test(s : Base) : Boolean = code(s) == 0 + +fun box() : String { + if (!test(new Base())) return "Fail #1" + if (!test(new Derived1())) return "Fail #2" + if (!test(new Derived2())) return "Fail #3" + return "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 62a5747e287..6c66f0e6754 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -32,6 +32,10 @@ public class ClassGenTest extends CodegenTestCase { blackBoxFile("funDelegation.jet"); } + public void testPropertyDelegation() throws Exception { + blackBoxFile("propertyDelegation.jet"); + } + private static void checkInterface(Class aClass, Class ifs) { for (Class anInterface : aClass.getInterfaces()) { if (anInterface == ifs) return; diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index 77b36138e23..ec83f12b8c5 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -42,6 +42,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { protected void blackBoxFile(String filename) throws Exception { loadFile(filename); + //System.out.println(generateToText()); assertEquals("OK", blackBox()); }