From 6f41e3b462f849ee8d9f3bdd4bb79cfd7948b88f Mon Sep 17 00:00:00 2001 From: Michael Bogdanov Date: Tue, 19 Jul 2016 16:53:01 +0300 Subject: [PATCH] Fix for KT-11634: UOE in ConstructorContext.getOuterExpression for super call in delegation #KT-11634 Fixed --- .../codegen/ImplementationBodyCodegen.java | 12 ++++++++ .../testData/codegen/box/closures/kt11634.kt | 27 ++++++++++++++++++ .../codegen/box/closures/kt11634_2.kt | 27 ++++++++++++++++++ .../codegen/box/closures/kt11634_3.kt | 27 ++++++++++++++++++ .../codegen/box/closures/kt11634_4.kt | 28 +++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 24 ++++++++++++++++ 6 files changed, 145 insertions(+) create mode 100644 compiler/testData/codegen/box/closures/kt11634.kt create mode 100644 compiler/testData/codegen/box/closures/kt11634_2.kt create mode 100644 compiler/testData/codegen/box/closures/kt11634_3.kt create mode 100644 compiler/testData/codegen/box/closures/kt11634_4.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java index c8d6d6df342..eb8cec68199 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ImplementationBodyCodegen.java @@ -1274,6 +1274,18 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen { } } } + + @Override + public void visitSuperExpression(@NotNull KtSuperExpression expression) { + KotlinType thisTypeForSuperCall = bindingContext.get(BindingContext.THIS_TYPE_FOR_SUPER_EXPRESSION, expression); + assert thisTypeForSuperCall != null : "This type for superCall ''" + expression.getText() + "'' should be not null!"; + ClassifierDescriptor descriptor = thisTypeForSuperCall.getConstructor().getDeclarationDescriptor(); + assert descriptor instanceof ClassDescriptor : + "'This' reference target for ''" + expression.getText() + "''should be class descriptor, but was " + descriptor; + if (descriptor instanceof ClassDescriptor) { + lookupInContext(descriptor); + } + } }; for (KtDeclaration declaration : myClass.getDeclarations()) { diff --git a/compiler/testData/codegen/box/closures/kt11634.kt b/compiler/testData/codegen/box/closures/kt11634.kt new file mode 100644 index 00000000000..7bd1880718f --- /dev/null +++ b/compiler/testData/codegen/box/closures/kt11634.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): String +} + +class AImpl(val z: String) : A { + override fun foo(): String = z +} + +open class AFabric { + open fun createA(): A = AImpl("OK") +} + +class AWrapperFabric : AFabric() { + + override fun createA(): A { + return AImpl("fail") + } + + fun createMyA(): A { + return object : A by super.createA() { + } + } +} + +fun box(): String { + return AWrapperFabric().createMyA().foo() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/closures/kt11634_2.kt b/compiler/testData/codegen/box/closures/kt11634_2.kt new file mode 100644 index 00000000000..1eb0e9ff096 --- /dev/null +++ b/compiler/testData/codegen/box/closures/kt11634_2.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): String +} + +class AImpl(val z: String) : A { + override fun foo(): String = z +} + +open class AFabric { + open fun createA(z: String): A = AImpl(z) +} + +class AWrapperFabric : AFabric() { + + override fun createA(z: String): A { + return AImpl("fail: $z") + } + + fun createMyA(): A { + val z = "OK" + return object : A by super.createA(z) {} + } +} + +fun box(): String { + return AWrapperFabric().createMyA().foo() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/closures/kt11634_3.kt b/compiler/testData/codegen/box/closures/kt11634_3.kt new file mode 100644 index 00000000000..1fdaa65c236 --- /dev/null +++ b/compiler/testData/codegen/box/closures/kt11634_3.kt @@ -0,0 +1,27 @@ +interface A { + fun foo(): String +} + +class AImpl(val z: String) : A { + override fun foo(): String = z +} + +open class AFabric { + open fun createA(z: String): A = AImpl(z) +} + +class AWrapperFabric : AFabric() { + + override fun createA(z: String): A { + return AImpl("fail: $z") + } + + fun createMyA(): A { + val z = "OK" + return object : A by super@AWrapperFabric.createA(z) {} + } +} + +fun box(): String { + return AWrapperFabric().createMyA().foo() +} \ No newline at end of file diff --git a/compiler/testData/codegen/box/closures/kt11634_4.kt b/compiler/testData/codegen/box/closures/kt11634_4.kt new file mode 100644 index 00000000000..08722aa81de --- /dev/null +++ b/compiler/testData/codegen/box/closures/kt11634_4.kt @@ -0,0 +1,28 @@ +interface A { + fun foo(): String +} + +open class Base (val p: String) { + open val a = object : A { + override fun foo(): String { + return p + } + } +} + +open class Derived1 (p: String): Base(p) { + override open val a = object : A { + override fun foo(): String { + return "fail" + } + } + + inner class Derived2(p: String) : Base(p) { + val x = object : A by super@Derived1.a {} + } + +} + +fun box(): String { + return Derived1("OK").Derived2("fail").x.foo() +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 8e2b49c5a57..9555c5167b0 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -3136,6 +3136,30 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("kt11634.kt") + public void testKt11634() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/kt11634.kt"); + doTest(fileName); + } + + @TestMetadata("kt11634_2.kt") + public void testKt11634_2() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/kt11634_2.kt"); + doTest(fileName); + } + + @TestMetadata("kt11634_3.kt") + public void testKt11634_3() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/kt11634_3.kt"); + doTest(fileName); + } + + @TestMetadata("kt11634_4.kt") + public void testKt11634_4() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/kt11634_4.kt"); + doTest(fileName); + } + @TestMetadata("kt2151.kt") public void testKt2151() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/closures/kt2151.kt");