function delegation

This commit is contained in:
Maxim Shafirov
2011-05-09 18:34:38 +04:00
parent a8d6c80588
commit a8a72a7fc0
5 changed files with 43 additions and 7 deletions
@@ -327,7 +327,6 @@ public class ClassCodegen {
final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, standardLibrary, bindingContext); final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, standardLibrary, bindingContext);
final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen); final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen);
/* TODO
for (JetDeclaration declaration : toClass.getDeclarations()) { for (JetDeclaration declaration : toClass.getDeclarations()) {
if (declaration instanceof JetProperty) { if (declaration instanceof JetProperty) {
propertyCodegen.gen((JetProperty) declaration, kind); propertyCodegen.gen((JetProperty) declaration, kind);
@@ -336,7 +335,6 @@ public class ClassCodegen {
functionCodegen.gen((JetFunction) declaration, kind); functionCodegen.gen((JetFunction) declaration, kind);
} }
} }
*/
for (JetParameter p : toClass.getPrimaryConstructorParameters()) { for (JetParameter p : toClass.getPrimaryConstructorParameters()) {
if (p.getValOrVarNode() != null) { if (p.getValOrVarNode() != null) {
@@ -7,6 +7,7 @@ import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import org.objectweb.asm.commons.Method; import org.objectweb.asm.commons.Method;
import java.util.List; import java.util.List;
@@ -61,8 +62,22 @@ public class FunctionCodegen {
} }
ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), ownerClass, kind); ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), ownerClass, kind);
bodyExpression.accept(codegen); if (kind instanceof OwnerKind.DelegateKind) {
generateReturn(mv, bodyExpression, codegen); OwnerKind.DelegateKind dk = (OwnerKind.DelegateKind) kind;
InstructionAdapter iv = new InstructionAdapter(mv);
iv.load(0, JetTypeMapper.TYPE_OBJECT);
dk.getDelegate().put(JetTypeMapper.TYPE_OBJECT, iv);
for (int i = 0; i < argTypes.length; i++) {
Type argType = argTypes[i];
iv.load(i + 1, argType);
}
iv.invokeinterface(dk.getOwnerClass(), jvmSignature.getName(), jvmSignature.getDescriptor());
iv.areturn(jvmSignature.getReturnType());
}
else {
bodyExpression.accept(codegen);
generateReturn(mv, bodyExpression, codegen);
}
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
} }
+17
View File
@@ -0,0 +1,17 @@
class Base() {
fun n(n : Int) : Int = n + 1
}
class Abstract {}
class Derived1() : Base(), Abstract {}
class Derived2() : Abstract, Base() {}
fun test(s : Base) : Boolean = s.n(238) == 239
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"
}
@@ -25,10 +25,11 @@ public class ClassGenTest extends CodegenTestCase {
} }
public void testInheritanceAndDelegation_DelegatingDefaultConstructorProperties() throws Exception { public void testInheritanceAndDelegation_DelegatingDefaultConstructorProperties() throws Exception {
loadFile("inheritance.jet"); blackBoxFile("inheritance.jet");
System.out.println(generateToText()); }
assertEquals("OK", blackBox()); public void testFunDelegation() throws Exception {
blackBoxFile("funDelegation.jet");
} }
private static void checkInterface(Class aClass, Class ifs) { private static void checkInterface(Class aClass, Class ifs) {
@@ -40,6 +40,11 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase {
myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name); myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name);
} }
protected void blackBoxFile(String filename) throws Exception {
loadFile(filename);
assertEquals("OK", blackBox());
}
protected String blackBox() throws Exception { protected String blackBox() throws Exception {
Codegens codegens = generateClassesInFile(); Codegens codegens = generateClassesInFile();
CodegensClassLoader loader = new CodegensClassLoader(codegens); CodegensClassLoader loader = new CodegensClassLoader(codegens);