From 70e01fac184f66b9b600c5d691837aebc2637583 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 15 Jul 2016 00:24:29 +0300 Subject: [PATCH] Fix class literals of objects in super constructor calls In an expression such as "Obj::class" where Obj is an object, it's fine to consider Obj either an expression or a type and generate either Obj.INSTANCE.getClass() or Obj.class correspondingly. However, the former fails in the object's super constructor call because the INSTANCE field is not yet initialized. Thus, we force generation of Obj.class in case when Obj is an object. Note that this has been reproduced in our project, see KotlinMetadataVersionIndex --- .../kotlin/codegen/ExpressionCodegen.java | 4 ++-- .../bound/objectSuperConstructorCall.kt | 18 ++++++++++++++++++ .../codegen/BlackBoxCodegenTestGenerated.java | 6 ++++++ 3 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 compiler/testData/codegen/box/classLiteral/bound/objectSuperConstructorCall.kt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index 62fd52e6ce4..a74cfcc6d29 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -3290,10 +3290,10 @@ public class ExpressionCodegen extends KtVisitor impleme @Override public Unit invoke(InstructionAdapter v) { KotlinType type = lhs.getType(); - if (lhs instanceof DoubleColonLHS.Expression) { + if (lhs instanceof DoubleColonLHS.Expression && !((DoubleColonLHS.Expression) lhs).isObject()) { JavaClassProperty.INSTANCE.generateImpl(v, gen(receiverExpression)); } - else if (lhs instanceof DoubleColonLHS.Type) { + else { if (TypeUtils.isTypeParameter(type)) { assert TypeUtils.isReifiedTypeParameter(type) : "Non-reified type parameter under ::class should be rejected by type checker: " + type; diff --git a/compiler/testData/codegen/box/classLiteral/bound/objectSuperConstructorCall.kt b/compiler/testData/codegen/box/classLiteral/bound/objectSuperConstructorCall.kt new file mode 100644 index 00000000000..7b2dfdb3732 --- /dev/null +++ b/compiler/testData/codegen/box/classLiteral/bound/objectSuperConstructorCall.kt @@ -0,0 +1,18 @@ +// WITH_RUNTIME + +import kotlin.test.assertEquals + +abstract class S(val klass: Class) { + val result = klass.simpleName +} + +object OK : S(OK::class.java) + +class C { + companion object Companion : S(Companion::class.java) +} + +fun box(): String { + assertEquals("Companion", C.Companion.result) + return OK.result +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java index 9a38c2fae27..8944c72943d 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/BlackBoxCodegenTestGenerated.java @@ -2364,6 +2364,12 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { doTest(fileName); } + @TestMetadata("objectSuperConstructorCall.kt") + public void testObjectSuperConstructorCall() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classLiteral/bound/objectSuperConstructorCall.kt"); + doTest(fileName); + } + @TestMetadata("primitives.kt") public void testPrimitives() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/box/classLiteral/bound/primitives.kt");