diff --git a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java index 3116ca36515..d4221c3c571 100644 --- a/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ClassCodegen.java @@ -327,7 +327,6 @@ public class ClassCodegen { final FunctionCodegen functionCodegen = new FunctionCodegen(toClass, v, standardLibrary, bindingContext); final PropertyCodegen propertyCodegen = new PropertyCodegen(v, standardLibrary, bindingContext, functionCodegen); -/* TODO for (JetDeclaration declaration : toClass.getDeclarations()) { if (declaration instanceof JetProperty) { propertyCodegen.gen((JetProperty) declaration, kind); @@ -336,7 +335,6 @@ public class ClassCodegen { functionCodegen.gen((JetFunction) declaration, kind); } } -*/ for (JetParameter p : toClass.getPrimaryConstructorParameters()) { if (p.getValOrVarNode() != null) { diff --git a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java index 1573e81aebd..3d23b16fd1b 100644 --- a/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/FunctionCodegen.java @@ -7,6 +7,7 @@ import org.objectweb.asm.ClassVisitor; import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.Opcodes; import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; import org.objectweb.asm.commons.Method; import java.util.List; @@ -61,8 +62,22 @@ public class FunctionCodegen { } ExpressionCodegen codegen = new ExpressionCodegen(mv, bindingContext, frameMap, typeMapper, jvmSignature.getReturnType(), ownerClass, kind); - bodyExpression.accept(codegen); - generateReturn(mv, bodyExpression, codegen); + if (kind instanceof OwnerKind.DelegateKind) { + 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.visitEnd(); } diff --git a/idea/testData/codegen/funDelegation.jet b/idea/testData/codegen/funDelegation.jet new file mode 100644 index 00000000000..6af00871dd5 --- /dev/null +++ b/idea/testData/codegen/funDelegation.jet @@ -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" +} \ 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 6999f3e3b13..62a5747e287 100644 --- a/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java +++ b/idea/tests/org/jetbrains/jet/codegen/ClassGenTest.java @@ -25,10 +25,11 @@ public class ClassGenTest extends CodegenTestCase { } public void testInheritanceAndDelegation_DelegatingDefaultConstructorProperties() throws Exception { - loadFile("inheritance.jet"); - System.out.println(generateToText()); + blackBoxFile("inheritance.jet"); + } - assertEquals("OK", blackBox()); + public void testFunDelegation() throws Exception { + blackBoxFile("funDelegation.jet"); } private static void checkInterface(Class aClass, Class ifs) { diff --git a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java index a22e6e95449..77b36138e23 100644 --- a/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java +++ b/idea/tests/org/jetbrains/jet/codegen/CodegenTestCase.java @@ -40,6 +40,11 @@ public abstract class CodegenTestCase extends LightCodeInsightFixtureTestCase { myFixture.configureByFile(JetParsingTest.getTestDataDir() + "/codegen/" + name); } + protected void blackBoxFile(String filename) throws Exception { + loadFile(filename); + assertEquals("OK", blackBox()); + } + protected String blackBox() throws Exception { Codegens codegens = generateClassesInFile(); CodegensClassLoader loader = new CodegensClassLoader(codegens);