Delegating properties
This commit is contained in:
@@ -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());
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user