Delegating properties
This commit is contained in:
@@ -58,6 +58,12 @@ public class PropertyCodegen {
|
|||||||
null, null);
|
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) {
|
private void generateBackingField(JetProperty p, OwnerKind kind, PropertyDescriptor propertyDescriptor) {
|
||||||
@@ -179,17 +185,27 @@ public class PropertyCodegen {
|
|||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
InstructionAdapter iv = new InstructionAdapter(mv);
|
InstructionAdapter iv = new InstructionAdapter(mv);
|
||||||
final Type type = mapper.mapType(propertyDescriptor.getOutType());
|
final Type type = mapper.mapType(propertyDescriptor.getOutType());
|
||||||
|
int paramCode = 0;
|
||||||
if (kind != OwnerKind.NAMESPACE) {
|
if (kind != OwnerKind.NAMESPACE) {
|
||||||
iv.load(0, JetTypeMapper.TYPE_OBJECT);
|
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 {
|
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);
|
iv.visitInsn(Opcodes.RETURN);
|
||||||
mv.visitMaxs(0, 0);
|
mv.visitMaxs(0, 0);
|
||||||
mv.visitEnd();
|
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");
|
blackBoxFile("funDelegation.jet");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testPropertyDelegation() throws Exception {
|
||||||
|
blackBoxFile("propertyDelegation.jet");
|
||||||
|
}
|
||||||
|
|
||||||
private static void checkInterface(Class aClass, Class ifs) {
|
private static void checkInterface(Class aClass, Class ifs) {
|
||||||
for (Class anInterface : aClass.getInterfaces()) {
|
for (Class anInterface : aClass.getInterfaces()) {
|
||||||
if (anInterface == ifs) return;
|
if (anInterface == ifs) return;
|
||||||
|
|||||||
@@ -42,6 +42,7 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
|
|||||||
|
|
||||||
protected void blackBoxFile(String filename) throws Exception {
|
protected void blackBoxFile(String filename) throws Exception {
|
||||||
loadFile(filename);
|
loadFile(filename);
|
||||||
|
//System.out.println(generateToText());
|
||||||
assertEquals("OK", blackBox());
|
assertEquals("OK", blackBox());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user