From 9a8cf23ed44ed0d4062733e12963279ec29ea6bb Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 25 Aug 2015 09:34:45 +0300 Subject: [PATCH] Support KClass.companionObject and companionObjectInstance #KT-7636 Fixed --- .../reflection/classes/companionObject.kt | 20 +++++++++++++++++++ ...lackBoxWithStdlibCodegenTestGenerated.java | 6 ++++++ .../src/kotlin/reflect/KClassExtensions.kt | 18 +++++++++++++++++ 3 files changed, 44 insertions(+) create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/classes/companionObject.kt diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/classes/companionObject.kt b/compiler/testData/codegen/boxWithStdlib/reflection/classes/companionObject.kt new file mode 100644 index 00000000000..097a2b52afa --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/classes/companionObject.kt @@ -0,0 +1,20 @@ +import kotlin.reflect.* +import kotlin.test.* + +class A { + companion object C +} + +fun box(): String { + val obj = A::class.companionObject + assertNotNull(obj) + assertEquals("C", obj!!.simpleName) + + assertEquals(A.C, A::class.companionObjectInstance) + assertEquals(A.C, obj.objectInstance) + + assertNull(A.C::class.companionObject) + assertNull(A.C::class.companionObjectInstance) + + return "OK" +} diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index bb927520144..11341758ce5 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -3012,6 +3012,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("companionObject.kt") + public void testCompanionObject() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classes/companionObject.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("defaultType.kt") public void testDefaultType() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classes/defaultType.kt"); diff --git a/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt b/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt index a4a2ec24650..837fcece7b4 100644 --- a/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt +++ b/core/reflection.jvm/src/kotlin/reflect/KClassExtensions.kt @@ -31,6 +31,24 @@ public val KClass.primaryConstructor: KFunction? ((it as KFunctionImpl).descriptor as ConstructorDescriptor).isPrimary } + +/** + * Returns a [KClass] instance representing the companion object of a given class, + * or `null` if the class doesn't have a companion object. + */ +public val KClass<*>.companionObject: KClass<*>? + get() = nestedClasses.firstOrNull { + (it as KClassImpl<*>).descriptor.isCompanionObject + } + +/** + * Returns an instance of the companion object of a given class, + * or `null` if the class doesn't have a companion object. + */ +public val KClass<*>.companionObjectInstance: Any? + get() = companionObject?.objectInstance + + /** * Returns a type corresponding to the given class with type parameters of that class substituted as the corresponding arguments. * For example, for class `MyMap` [defaultType] would return the type `MyMap`.