diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index e748ff55a09..73d8f961c17 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1747,8 +1747,13 @@ public class ExpressionCodegen extends JetVisitor implem boolean superCall = isSuperCall(call); if (superCall && !isInterface(fd.getContainingDeclaration())) { - CodegenContext c = getParentContextSubclassOf((ClassDescriptor) fd.getContainingDeclaration()); - fd = (FunctionDescriptor) c.getAccessor(unwrapFakeOverride(fd)); + JetSuperExpression expression = getSuperCallExpression(call); + ClassDescriptor owner = getSuperCallLabelTarget(expression); + CodegenContext c = context.findParentContextWithDescriptor(owner); + assert c != null : "Couldn't find a context for a super-call: " + fd; + if (c != context.getParentContext()) { + fd = (FunctionDescriptor) c.getAccessor(unwrapFakeOverride(fd)); + } } fd = accessableFunctionDescriptor(fd); diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java index faf80a9ed38..6dd815ea2d5 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/context/CodegenContext.java @@ -217,6 +217,16 @@ public abstract class CodegenContext { return cur == null ? null : (ClassDescriptor) cur.getContextDescriptor(); } + @Nullable + public CodegenContext findParentContextWithDescriptor(DeclarationDescriptor descriptor) { + CodegenContext c = this; + while (c != null) { + if (c.getContextDescriptor() == descriptor) break; + c = c.getParentContext(); + } + return c; + } + public DeclarationDescriptor getAccessor(DeclarationDescriptor descriptor) { if (accessors == null) { accessors = new HashMap(); diff --git a/compiler/testData/codegen/super/kt2887.kt b/compiler/testData/codegen/super/kt2887.kt new file mode 100644 index 00000000000..ed6adf83b7b --- /dev/null +++ b/compiler/testData/codegen/super/kt2887.kt @@ -0,0 +1,16 @@ +open class Base { + public open fun foo(t: T): T = t + + public open fun bar() {} +} + +class Child: Base() { + override fun foo(t: String): String { + return super.foo(t) + } + + override fun bar() { + super.bar() + } + +} diff --git a/compiler/tests/org/jetbrains/jet/codegen/SuperGenTest.java b/compiler/tests/org/jetbrains/jet/codegen/SuperGenTest.java index 27f1f979046..1dd278c3682 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/SuperGenTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/SuperGenTest.java @@ -16,6 +16,7 @@ package org.jetbrains.jet.codegen; +import org.apache.commons.lang.StringUtils; import org.jetbrains.jet.ConfigurationKind; public class SuperGenTest extends CodegenTestCase { @@ -28,22 +29,18 @@ public class SuperGenTest extends CodegenTestCase { public void testBasicProperty () { blackBoxFile("/super/basicproperty.jet"); -// System.out.println(generateToText()); } public void testTraitProperty () { blackBoxFile("/super/traitproperty.jet"); -// System.out.println(generateToText()); } public void testBasicMethodSuperTrait () { blackBoxFile("/super/basicmethodSuperTrait.jet"); -// System.out.println(generateToText()); } public void testBasicMethodSuperClass () { blackBoxFile("/super/basicmethodSuperClass.jet"); -// System.out.println(generateToText()); } public void testInnerClassLabeledSuper() { @@ -60,12 +57,16 @@ public class SuperGenTest extends CodegenTestCase { public void testEnclosedFun () { blackBoxFile("/super/enclosedFun.jet"); -// System.out.println(generateToText()); } public void testEnclosedVar () { blackBoxFile("/super/enclosedVar.jet"); -// System.out.println(generateToText()); } + public void testKt2887() { + loadFile("super/kt2887.kt"); + String text = generateToText(); + // There should be exactly one bridge in this example + assertEquals(1, StringUtils.countMatches(text, "bridge")); + } }