From 6182b3ff5c81a65d53971424185eb3a98d781341 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 8 Apr 2015 16:35:39 +0300 Subject: [PATCH] Prohibit Array::class, require type arguments for reified parameters --- .../kotlin/codegen/ExpressionCodegen.java | 17 ++--- .../jetbrains/kotlin/diagnostics/Errors.java | 1 + .../rendering/DefaultErrorMessages.java | 1 + .../BasicExpressionTypingVisitor.java | 68 ++++++++++++++----- .../kotlin/types/reflect/ReflectionTypes.kt | 19 ++---- .../property/extensionToArray.kt | 6 ++ .../reflection/classLiterals/arrays.kt | 12 ++++ .../classLiterals/builtinClassLiterals.kt | 3 + .../methodsFromAny/classToString.kt | 6 +- .../testsWithStdLib/classLiteral/arrays.kt | 5 ++ .../testsWithStdLib/classLiteral/arrays.txt | 7 ++ .../classLiteral/nonClassesOnLHS.kt | 2 + .../classLiteral/nonClassesOnLHS.txt | 1 + ...JetDiagnosticsTestWithStdLibGenerated.java | 6 ++ ...lackBoxWithStdlibCodegenTestGenerated.java | 12 ++++ .../kotlin/builtins/KotlinBuiltIns.java | 4 ++ .../reflect/jvm/internal/RuntimeTypeMapper.kt | 6 ++ 17 files changed, 137 insertions(+), 39 deletions(-) create mode 100644 compiler/testData/codegen/boxWithStdlib/callableReference/property/extensionToArray.kt create mode 100644 compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/arrays.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.kt create mode 100644 compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.txt diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java index d8356948777..7372ba0a497 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/ExpressionCodegen.java @@ -36,7 +36,9 @@ import org.jetbrains.kotlin.codegen.binding.CalculatedClosure; import org.jetbrains.kotlin.codegen.context.*; import org.jetbrains.kotlin.codegen.extensions.ExpressionCodegenExtension; import org.jetbrains.kotlin.codegen.inline.*; -import org.jetbrains.kotlin.codegen.intrinsics.*; +import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethod; +import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods; +import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty; import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter; import org.jetbrains.kotlin.codegen.state.GenerationState; import org.jetbrains.kotlin.codegen.state.JetTypeMapper; @@ -2668,10 +2670,7 @@ public class ExpressionCodegen extends JetVisitor implem assert state.getReflectionTypes().getkClass().getTypeConstructor().equals(type.getConstructor()) : "::class expression should be type checked to a KClass: " + type; - ClassifierDescriptor typeArgument = KotlinPackage.single(type.getArguments()).getType().getConstructor().getDeclarationDescriptor(); - assert typeArgument instanceof ClassDescriptor : "KClass argument should be a class: " + typeArgument; - - return generateClassLiteralReference((ClassDescriptor) typeArgument); + return generateClassLiteralReference(KotlinPackage.single(type.getArguments()).getType()); } @Override @@ -2763,7 +2762,7 @@ public class ExpressionCodegen extends JetVisitor implem @Override public Unit invoke(InstructionAdapter v) { v.visitLdcInsn(descriptor.getName().asString()); - StackValue receiverClass = generateClassLiteralReference(containingClass); + StackValue receiverClass = generateClassLiteralReference(containingClass.getDefaultType()); receiverClass.put(receiverClass.type, v); v.invokestatic(REFLECTION, factoryMethod.getName(), factoryMethod.getDescriptor(), false); @@ -2773,11 +2772,13 @@ public class ExpressionCodegen extends JetVisitor implem } @NotNull - private StackValue generateClassLiteralReference(@NotNull final ClassDescriptor descriptor) { + private StackValue generateClassLiteralReference(@NotNull final JetType type) { return StackValue.operation(K_CLASS_TYPE, new Function1() { @Override public Unit invoke(InstructionAdapter v) { - Type classAsmType = typeMapper.mapClass(descriptor); + Type classAsmType = typeMapper.mapType(type); + ClassifierDescriptor descriptor = type.getConstructor().getDeclarationDescriptor(); + //noinspection ConstantConditions ModuleDescriptor module = DescriptorUtils.getContainingModule(descriptor); if (descriptor instanceof JavaClassDescriptor || module == module.getBuiltIns().getBuiltInsModule()) { putJavaLangClassInstance(v, classAsmType); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java index bff6e26e6c4..721e5ead1de 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/Errors.java @@ -440,6 +440,7 @@ public interface Errors { DiagnosticFactory0 CALLABLE_REFERENCE_LHS_NOT_A_CLASS = DiagnosticFactory0.create(ERROR); DiagnosticFactory0 CLASS_LITERAL_LHS_NOT_A_CLASS = DiagnosticFactory0.create(ERROR); + DiagnosticFactory0 ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT = DiagnosticFactory0.create(ERROR); // Multi-declarations diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 6338c8c4337..42408115f65 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -589,6 +589,7 @@ public class DefaultErrorMessages { MAP.put(CALLABLE_REFERENCE_LHS_NOT_A_CLASS, "Left hand side of a callable reference cannot be a type parameter"); MAP.put(CLASS_LITERAL_LHS_NOT_A_CLASS, "Only classes are allowed on the left hand side of a class literal"); + MAP.put(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT, "kotlin.Array class literal requires a type argument, please specify one in angle brackets"); //Inline MAP.put(INVISIBLE_MEMBER_FROM_INLINE, "Cannot access effectively non-public-api ''{0}'' member from effectively public-api ''{1}''", SHORT_NAMES_IN_TYPES, SHORT_NAMES_IN_TYPES); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index cf3dba12770..b42a76cd817 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -22,6 +22,7 @@ import com.intellij.psi.tree.IElementType; import com.intellij.psi.tree.TokenSet; import kotlin.Function0; import kotlin.Function1; +import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.builtins.KotlinBuiltIns; @@ -451,11 +452,11 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { @Override public JetTypeInfo visitClassLiteralExpression(@NotNull JetClassLiteralExpression expression, ExpressionTypingContext c) { - ClassDescriptor descriptor = resolveClassLiteral(expression, c); - if (descriptor != null && !ErrorUtils.isError(descriptor)) { - JetType type = components.reflectionTypes.getKClassType(Annotations.EMPTY, descriptor); - if (!type.isError()) { - return JetTypeInfo.create(type, c.dataFlowInfo); + JetType type = resolveClassLiteral(expression, c); + if (type != null && !type.isError()) { + JetType kClassType = components.reflectionTypes.getKClassType(Annotations.EMPTY, type); + if (!kClassType.isError()) { + return JetTypeInfo.create(kClassType, c.dataFlowInfo); } c.trace.report(REFLECTION_TYPES_NOT_LOADED.on(expression.getDoubleColonTokenReference())); } @@ -464,7 +465,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { } @Nullable - private ClassDescriptor resolveClassLiteral(@NotNull JetClassLiteralExpression expression, ExpressionTypingContext c) { + private JetType resolveClassLiteral(@NotNull JetClassLiteralExpression expression, ExpressionTypingContext c) { JetTypeReference typeReference = expression.getTypeReference(); if (typeReference == null) { @@ -478,30 +479,65 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { PossiblyBareType possiblyBareType = components.expressionTypingServices.getTypeResolver().resolvePossiblyBareType(context, typeReference); - TypeConstructor typeConstructor = null; + JetType type = null; if (possiblyBareType.isBare()) { if (!possiblyBareType.isNullable()) { - typeConstructor = possiblyBareType.getBareTypeConstructor(); + ClassifierDescriptor descriptor = possiblyBareType.getBareTypeConstructor().getDeclarationDescriptor(); + if (descriptor instanceof ClassDescriptor) { + ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; + if (KotlinBuiltIns.isNonPrimitiveArray(classDescriptor)) { + context.trace.report(ARRAY_CLASS_LITERAL_REQUIRES_ARGUMENT.on(expression)); + return null; + } + type = substituteWithStarProjections(classDescriptor); + } } } else { - JetType type = possiblyBareType.getActualType(); - if (!type.isMarkedNullable() && type.getArguments().isEmpty()) { - typeConstructor = type.getConstructor(); + JetType actualType = possiblyBareType.getActualType(); + if (isAllowedInClassLiteral(actualType)) { + type = actualType; } } - if (typeConstructor != null) { - ClassifierDescriptor classifier = typeConstructor.getDeclarationDescriptor(); - if (classifier instanceof ClassDescriptor) { - return (ClassDescriptor) classifier; - } + if (type != null) { + return type; } context.trace.report(CLASS_LITERAL_LHS_NOT_A_CLASS.on(expression)); return null; } + @NotNull + private static JetType substituteWithStarProjections(@NotNull ClassDescriptor descriptor) { + TypeConstructor typeConstructor = descriptor.getTypeConstructor(); + List arguments = + KotlinPackage.map(typeConstructor.getParameters(), new Function1() { + @Override + public TypeProjection invoke(TypeParameterDescriptor descriptor) { + return TypeUtils.makeStarProjection(descriptor); + } + }); + + return new JetTypeImpl(Annotations.EMPTY, typeConstructor, false, arguments, descriptor.getMemberScope(arguments)); + } + + private static boolean isAllowedInClassLiteral(@NotNull JetType type) { + if (type.isMarkedNullable()) return false; + + TypeConstructor typeConstructor = type.getConstructor(); + if (!(typeConstructor.getDeclarationDescriptor() instanceof ClassDescriptor)) return false; + + List parameters = typeConstructor.getParameters(); + if (parameters.size() != type.getArguments().size()) return false; + + for (TypeParameterDescriptor parameter : parameters) { + if (!parameter.isReified()) return false; + } + + return true; + } + @Override public JetTypeInfo visitCallableReferenceExpression(@NotNull JetCallableReferenceExpression expression, ExpressionTypingContext c) { JetTypeReference typeReference = expression.getTypeReference(); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/reflect/ReflectionTypes.kt b/compiler/frontend/src/org/jetbrains/kotlin/types/reflect/ReflectionTypes.kt index 5d6b023f71d..b7a638c804f 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/reflect/ReflectionTypes.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/reflect/ReflectionTypes.kt @@ -26,7 +26,6 @@ import org.jetbrains.kotlin.name.isSubpackageOf import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.scopes.JetScope import org.jetbrains.kotlin.types.* -import org.jetbrains.kotlin.types.TypeUtils.makeStarProjection import java.util.ArrayList import kotlin.properties.Delegates @@ -61,20 +60,14 @@ public class ReflectionTypes(private val module: ModuleDescriptor) { public val kTopLevelExtensionProperty: ClassDescriptor by ClassLookup public val kMutableTopLevelExtensionProperty: ClassDescriptor by ClassLookup - public fun getKClassType(annotations: Annotations, classDescriptor: ClassDescriptor): JetType { - val kClassDescriptor = kClass - if (ErrorUtils.isError(kClassDescriptor)) { - return kClassDescriptor.getDefaultType() + public fun getKClassType(annotations: Annotations, type: JetType): JetType { + val descriptor = kClass + if (ErrorUtils.isError(descriptor)) { + return descriptor.getDefaultType() } - val typeConstructor = classDescriptor.getTypeConstructor() - val arguments = typeConstructor.getParameters().map(TypeUtils::makeStarProjection) - val kClassArguments = listOf(TypeProjectionImpl( - Variance.INVARIANT, - JetTypeImpl(Annotations.EMPTY, typeConstructor, false, arguments, classDescriptor.getMemberScope(arguments)) - )) - return JetTypeImpl(annotations, kClassDescriptor.getTypeConstructor(), false, kClassArguments, - kClassDescriptor.getMemberScope(kClassArguments)) + val arguments = listOf(TypeProjectionImpl(Variance.INVARIANT, type)) + return JetTypeImpl(annotations, descriptor.getTypeConstructor(), false, arguments, descriptor.getMemberScope(arguments)) } public fun getKFunctionType( diff --git a/compiler/testData/codegen/boxWithStdlib/callableReference/property/extensionToArray.kt b/compiler/testData/codegen/boxWithStdlib/callableReference/property/extensionToArray.kt new file mode 100644 index 00000000000..d80032edb5f --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/callableReference/property/extensionToArray.kt @@ -0,0 +1,6 @@ +val Array.firstElement: String get() = get(0) + +fun box(): String { + val p = Array::firstElement + return p.get(array("OK", "Fail")) +} diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/arrays.kt b/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/arrays.kt new file mode 100644 index 00000000000..6dad60a22ee --- /dev/null +++ b/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/arrays.kt @@ -0,0 +1,12 @@ +import kotlin.test.* +import kotlin.reflect.jvm.* + +fun box(): String { + val any = Array::class + val string = Array::class + + assertNotEquals(any, string) + assertNotEquals(any.java, string.java) + + return "OK" +} diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/builtinClassLiterals.kt b/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/builtinClassLiterals.kt index 5117554f309..9d716000f73 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/builtinClassLiterals.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/builtinClassLiterals.kt @@ -8,6 +8,9 @@ fun box(): String { assertEquals("Int", Int::class.simpleName) assertEquals("Long", Long::class.simpleName) + assertEquals("Array", Array::class.simpleName) + assertEquals("Array", Array::class.simpleName) + assertEquals("Companion", Int.Companion::class.simpleName) assertEquals("Companion", Double.Companion::class.simpleName) assertEquals("Companion", Char.Companion::class.simpleName) diff --git a/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt b/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt index 5302d7d8470..57c2a3a748c 100644 --- a/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt +++ b/compiler/testData/codegen/boxWithStdlib/reflection/methodsFromAny/classToString.kt @@ -15,11 +15,13 @@ fun box(): String { assertEquals("class kotlin.Int", "${Int::class}") assertEquals("class kotlin.Int\$Companion", "${Int.Companion::class}") assertEquals("class kotlin.IntArray", "${IntArray::class}") - // TODO - // assertEquals("class kotlin.Array", "${Array::class}") assertEquals("class kotlin.String", "${String::class}") assertEquals("class kotlin.String", "${java.lang.String::class}") + assertEquals("class kotlin.Array", "${Array::class}") + assertEquals("class kotlin.Array", "${Array::class}") + assertEquals("class kotlin.Array", "${Array>::class}") + assertEquals("class java.lang.Runnable", "${Runnable::class}") return "OK" diff --git a/compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.kt b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.kt new file mode 100644 index 00000000000..5abe3339e9c --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.kt @@ -0,0 +1,5 @@ +val a01 = Array::class +val a02 = Array<Array>::class +val a03 = Array::class +val a04 = Array?>::class +val a05 = Array::class diff --git a/compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.txt b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.txt new file mode 100644 index 00000000000..25db3962249 --- /dev/null +++ b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.txt @@ -0,0 +1,7 @@ +package + +internal val a01: [ERROR : Unresolved class] +internal val a02: kotlin.reflect.KClass> +internal val a03: kotlin.reflect.KClass> +internal val a04: kotlin.reflect.KClass?>> +internal val a05: kotlin.reflect.KClass> diff --git a/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.kt b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.kt index 4d7ae895547..2cf9f7462bd 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.kt @@ -12,3 +12,5 @@ fun foo() { val t1 = T::class val t2 = T?::class } + +val m = Map::class diff --git a/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.txt b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.txt index 114dfe03165..2067973b4f5 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.txt +++ b/compiler/testData/diagnostics/testsWithStdLib/classLiteral/nonClassesOnLHS.txt @@ -4,6 +4,7 @@ internal val a1: [ERROR : Unresolved class] internal val a2: [ERROR : Unresolved class] internal val l1: [ERROR : Unresolved class] internal val l2: [ERROR : Unresolved class] +internal val m: [ERROR : Unresolved class] internal fun foo(): kotlin.Unit internal final class A { diff --git a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java index 606253ba2b8..6bba7f4ac36 100644 --- a/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/checkers/JetDiagnosticsTestWithStdLibGenerated.java @@ -733,6 +733,12 @@ public class JetDiagnosticsTestWithStdLibGenerated extends AbstractJetDiagnostic JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/diagnostics/testsWithStdLib/classLiteral"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("arrays.kt") + public void testArrays() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/classLiteral/arrays.kt"); + doTest(fileName); + } + @TestMetadata("genericClasses.kt") public void testGenericClasses() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/classLiteral/genericClasses.kt"); diff --git a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java index 0b5b32da0c5..f2462a1622e 100644 --- a/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/codegen/generated/BlackBoxWithStdlibCodegenTestGenerated.java @@ -758,6 +758,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode doTestWithStdlib(fileName); } + @TestMetadata("extensionToArray.kt") + public void testExtensionToArray() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/property/extensionToArray.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("genericProperty.kt") public void testGenericProperty() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/callableReference/property/genericProperty.kt"); @@ -2709,6 +2715,12 @@ public class BlackBoxWithStdlibCodegenTestGenerated extends AbstractBlackBoxCode JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals"), Pattern.compile("^(.+)\\.kt$"), true); } + @TestMetadata("arrays.kt") + public void testArrays() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/arrays.kt"); + doTestWithStdlib(fileName); + } + @TestMetadata("builtinClassLiterals.kt") public void testBuiltinClassLiterals() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/codegen/boxWithStdlib/reflection/classLiterals/builtinClassLiterals.kt"); diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java index d5026b1a6f8..d79279617c0 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/KotlinBuiltIns.java @@ -853,6 +853,10 @@ public class KotlinBuiltIns { return type != null && isNotNullConstructedFromGivenClass(type, FQ_NAMES.string); } + public static boolean isNonPrimitiveArray(@NotNull ClassDescriptor descriptor) { + return FQ_NAMES.array.equals(DescriptorUtils.getFqName(descriptor)); + } + public static boolean isCloneable(@NotNull ClassDescriptor descriptor) { return FQ_NAMES.cloneable.equals(DescriptorUtils.getFqName(descriptor)); } diff --git a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt index 146250b9541..5101bff3f25 100644 --- a/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt +++ b/core/reflection.jvm/src/kotlin/reflect/jvm/internal/RuntimeTypeMapper.kt @@ -34,6 +34,8 @@ import org.jetbrains.kotlin.types.TypeUtils import kotlin.reflect.KotlinReflectionInternalError object RuntimeTypeMapper : JavaToKotlinClassMapBuilder() { + private val kotlinArrayClassId = KotlinBuiltIns.getInstance().getArray().classId + private val kotlinFqNameToJvmDesc = linkedMapOf() private val kotlinFqNameToJvmDescNullable = linkedMapOf() private val jvmDescToKotlinClassId = linkedMapOf() @@ -110,6 +112,10 @@ object RuntimeTypeMapper : JavaToKotlinClassMapBuilder() { } fun mapJvmClassToKotlinClassId(klass: Class<*>): ClassId { + if (klass.isArray() && !klass.getComponentType().isPrimitive()) { + return kotlinArrayClassId + } + return jvmDescToKotlinClassId[klass.desc] ?: klass.classId }