Delegating properties

This commit is contained in:
Maxim Shafirov
2011-05-09 18:56:23 +04:00
parent a8a72a7fc0
commit ec4bda880d
4 changed files with 60 additions and 6 deletions
@@ -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();
@@ -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"
}
@@ -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;
@@ -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());
}