diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt index 7cd0761b756..a53230fa41d 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/KClassImpl.kt @@ -20,13 +20,10 @@ 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.structure.reflect.safeClassLoader import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader 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.MemberScope import org.jetbrains.kotlin.serialization.deserialization.findClassAcrossModuleDependencies @@ -120,16 +117,9 @@ internal class KClassImpl(override val jClass: Class) : KDeclaration override val nestedClasses: Collection> get() = descriptor.unsubstitutedInnerClassesScope.getContributedDescriptors().filterNot(DescriptorUtils::isEnumEntry).mapNotNull { nestedClass -> - (nestedClass as ClassDescriptor).toJavaClass() ?: run { - // 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 - (this as Any).javaClass.safeClassLoader.tryLoadClass("$packageName.$className") - } - }.map { KClassImpl(it) } + val jClass = (nestedClass as ClassDescriptor).toJavaClass() + jClass?.let { KClassImpl(it) } + } @Suppress("UNCHECKED_CAST") private val objectInstance_ = ReflectProperties.lazy { diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt index 61e6424bd0d..b79f52b6968 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/util.kt @@ -18,10 +18,15 @@ package kotlin.reflect.jvm.internal import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.load.java.components.RuntimeSourceElementFactory +import org.jetbrains.kotlin.load.java.reflect.tryLoadClass 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.FqName +import org.jetbrains.kotlin.platform.JavaToKotlinClassMap +import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.descriptorUtil.classId import kotlin.jvm.internal.FunctionReference import kotlin.jvm.internal.PropertyReference import kotlin.reflect.IllegalCallableAccessException @@ -38,12 +43,36 @@ internal fun ClassDescriptor.toJavaClass(): Class<*>? { (source.javaElement as ReflectJavaClass).element } else -> { - // This is a built-in class - null + // If this is neither a Kotlin class nor a Java class, it is either a built-in or some fake class descriptor like the one + // that's created for java.io.Serializable in JvmBuiltInsSettings + val classId = JavaToKotlinClassMap.INSTANCE.mapKotlinToJava(DescriptorUtils.getFqName(this)) ?: classId + val packageName = classId.packageFqName.asString() + val className = classId.relativeClassName.asString() + // All pseudo-classes like kotlin.String.Companion must be accessible from the current class loader + loadClass(javaClass.safeClassLoader, packageName, className) } } } +internal fun loadClass(classLoader: ClassLoader, packageName: String, className: String): Class<*>? { + if (packageName == "kotlin") { + // See mapBuiltInType() in typeSignatureMapping.kt + when (className) { + "Array" -> return Array::class.java + "BooleanArray" -> return BooleanArray::class.java + "ByteArray" -> return ByteArray::class.java + "CharArray" -> return CharArray::class.java + "DoubleArray" -> return DoubleArray::class.java + "FloatArray" -> return FloatArray::class.java + "IntArray" -> return IntArray::class.java + "LongArray" -> return LongArray::class.java + "ShortArray" -> return ShortArray::class.java + } + } + + return classLoader.tryLoadClass("$packageName.${className.replace('.', '$')}") +} + // TODO: wrap other exceptions internal inline fun reflectionCall(block: () -> R): R = try {