Fix loading of class literal constant values in reflection
This is an addition to c1ab08c8ce where KT-26582 was fixed. The test
testClassLiteralArguments in JvmRuntimeDescriptorLoaderTestGenerated
failed before this change but went unnoticed because it wasn't run on CI
(see the previous commit)
This commit is contained in:
+7
-6
@@ -280,22 +280,23 @@ public abstract class FileBasedKotlinClass implements KotlinJvmBinaryClass {
|
|||||||
return resolveNameByInternalName(name, innerClasses);
|
return resolveNameByInternalName(name, innerClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See ReflectKotlinStructure.classLiteralValue
|
||||||
@NotNull
|
@NotNull
|
||||||
private static ClassLiteralValue resolveKotlinNameByType(@NotNull Type type, @NotNull InnerClassesInfo innerClasses) {
|
private static ClassLiteralValue resolveKotlinNameByType(@NotNull Type type, @NotNull InnerClassesInfo innerClasses) {
|
||||||
String typeDesc = type.getDescriptor();
|
String typeDesc = type.getDescriptor();
|
||||||
int nestedness = typeDesc.charAt(0) == '[' ? type.getDimensions() : 0;
|
int dimensions = typeDesc.charAt(0) == '[' ? type.getDimensions() : 0;
|
||||||
String elementDesc = nestedness == 0 ? typeDesc : type.getElementType().getDescriptor();
|
String elementDesc = dimensions == 0 ? typeDesc : type.getElementType().getDescriptor();
|
||||||
JvmPrimitiveType primType = JvmPrimitiveType.getByDesc(elementDesc);
|
JvmPrimitiveType primType = JvmPrimitiveType.getByDesc(elementDesc);
|
||||||
if (primType != null) {
|
if (primType != null) {
|
||||||
if (nestedness > 0) {
|
if (dimensions > 0) {
|
||||||
// "int[][]" should be loaded as "Array<IntArray>", not as "Array<Array<Int>>"
|
// "int[][]" should be loaded as "Array<IntArray>", not as "Array<Array<Int>>"
|
||||||
return new ClassLiteralValue(ClassId.topLevel(primType.getPrimitiveType().getArrayTypeFqName()), nestedness - 1);
|
return new ClassLiteralValue(ClassId.topLevel(primType.getPrimitiveType().getArrayTypeFqName()), dimensions - 1);
|
||||||
}
|
}
|
||||||
return new ClassLiteralValue(ClassId.topLevel(primType.getPrimitiveType().getTypeFqName()), nestedness);
|
return new ClassLiteralValue(ClassId.topLevel(primType.getPrimitiveType().getTypeFqName()), dimensions);
|
||||||
}
|
}
|
||||||
ClassId javaClassId = resolveNameByDesc(elementDesc, innerClasses);
|
ClassId javaClassId = resolveNameByDesc(elementDesc, innerClasses);
|
||||||
ClassId kotlinClassId = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(javaClassId.asSingleFqName());
|
ClassId kotlinClassId = JavaToKotlinClassMap.INSTANCE.mapJavaToKotlin(javaClassId.asSingleFqName());
|
||||||
return new ClassLiteralValue(kotlinClassId != null ? kotlinClassId : javaClassId, nestedness);
|
return new ClassLiteralValue(kotlinClassId != null ? kotlinClassId : javaClassId, dimensions);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
+15
-6
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package kotlin.reflect.jvm.internal.components
|
package kotlin.reflect.jvm.internal.components
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
import org.jetbrains.kotlin.load.kotlin.KotlinJvmBinaryClass
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor
|
import org.jetbrains.kotlin.load.kotlin.header.ReadKotlinClassHeaderAnnotationVisitor
|
||||||
@@ -185,17 +186,25 @@ private object ReflectClassStructure {
|
|||||||
visitor.visitEnd()
|
visitor.visitEnd()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// See FileBasedKotlinClass.resolveKotlinNameByType
|
||||||
private fun Class<*>.classLiteralValue(): ClassLiteralValue {
|
private fun Class<*>.classLiteralValue(): ClassLiteralValue {
|
||||||
var currentClass = this
|
var currentClass = this
|
||||||
var nestedness = 0
|
var dimensions = 0
|
||||||
while (currentClass.isArray) {
|
while (currentClass.isArray) {
|
||||||
nestedness++
|
dimensions++
|
||||||
currentClass = currentClass.componentType
|
currentClass = currentClass.componentType
|
||||||
}
|
}
|
||||||
val classId =
|
if (currentClass.isPrimitive) {
|
||||||
if (!currentClass.isPrimitive) currentClass.classId
|
val primitiveType = JvmPrimitiveType.get(currentClass.name).primitiveType
|
||||||
else ClassId.topLevel(JvmPrimitiveType.get(currentClass.name).primitiveType.typeFqName)
|
if (dimensions > 0) {
|
||||||
return ClassLiteralValue(classId, nestedness)
|
return ClassLiteralValue(ClassId.topLevel(primitiveType.arrayTypeFqName), dimensions - 1)
|
||||||
|
}
|
||||||
|
return ClassLiteralValue(ClassId.topLevel(primitiveType.typeFqName), dimensions)
|
||||||
|
}
|
||||||
|
|
||||||
|
val javaClassId = currentClass.classId
|
||||||
|
val kotlinClassId = JavaToKotlinClassMap.mapJavaToKotlin(javaClassId.asSingleFqName()) ?: javaClassId
|
||||||
|
return ClassLiteralValue(kotlinClassId, dimensions)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun processAnnotationArgumentValue(visitor: KotlinJvmBinaryClass.AnnotationArgumentVisitor, name: Name, value: Any) {
|
private fun processAnnotationArgumentValue(visitor: KotlinJvmBinaryClass.AnnotationArgumentVisitor, name: Name, value: Any) {
|
||||||
|
|||||||
Reference in New Issue
Block a user