Support KClass.nestedClasses

This commit is contained in:
Alexander Udalov
2015-08-04 22:50:55 +03:00
parent e8dc9ede31
commit 94d45f35d4
9 changed files with 126 additions and 5 deletions
@@ -16,15 +16,20 @@
package kotlin.reflect.jvm.internal
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.ConstructorDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.reflect.tryLoadClass
import org.jetbrains.kotlin.load.java.sources.JavaSourceElement
import org.jetbrains.kotlin.load.java.structure.reflect.ReflectJavaClass
import org.jetbrains.kotlin.load.java.structure.reflect.safeClassLoader
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinarySourceElement
import org.jetbrains.kotlin.load.kotlin.reflect.ReflectKotlinClass
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.scopes.JetScope
import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies
import kotlin.reflect.KCallable
@@ -111,6 +116,27 @@ class KClassImpl<T : Any>(override val jClass: Class<T>) : KDeclarationContainer
KFunctionImpl(this, it) as KFunction<T>
}
override val nestedClasses: Collection<KClass<*>>
get() = descriptor.unsubstitutedInnerClassesScope.getAllDescriptors().map { nestedClass ->
val source = (nestedClass as DeclarationDescriptorWithSource).source
when (source) {
is KotlinJvmBinarySourceElement ->
(source.binaryClass as ReflectKotlinClass).klass
is JavaSourceElement ->
(source.javaElement as ReflectJavaClass).element
SourceElement.NO_SOURCE -> {
// If neither a Kotlin class nor a Java class, it must be a built-in
val classId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(DescriptorUtils.getFqName(nestedClass))
?: throw KotlinReflectionInternalError("Class with no source must be a built-in: $nestedClass")
val packageName = classId.packageFqName.asString()
val className = classId.relativeClassName.asString().replace('.', '$')
// All pseudo-classes like String.Companion must be accessible from the current class loader
javaClass.safeClassLoader.tryLoadClass("$packageName.$className")
}
else -> throw KotlinReflectionInternalError("Unsupported class: $nestedClass (source = $source)")
}
}.filterNotNull().map { KClassImpl(it) }
@suppress("UNCHECKED_CAST")
override val objectInstance: T? by ReflectProperties.lazy {
val descriptor = descriptor