diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt index e6bb6b6f2fa..d08a82a04e4 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaUtils.kt @@ -106,11 +106,12 @@ internal fun JavaClassifierType.toFirResolvedTypeRef( internal fun JavaType?.toConeKotlinTypeWithoutEnhancement( session: FirSession, - javaTypeParameterStack: JavaTypeParameterStack + javaTypeParameterStack: JavaTypeParameterStack, + forAnnotationValueParameter: Boolean = false ): ConeKotlinType { return when (this) { is JavaClassifierType -> { - toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) + toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forAnnotationValueParameter = forAnnotationValueParameter) } is JavaPrimitiveType -> { val primitiveType = type @@ -123,7 +124,7 @@ internal fun JavaType?.toConeKotlinTypeWithoutEnhancement( classId.toConeKotlinType(emptyArray(), isNullable = false) } is JavaArrayType -> { - toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) + toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forAnnotationValueParameter) } is JavaWildcardType -> bound?.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) ?: run { StandardClassIds.Any.toConeFlexibleType(emptyArray()) @@ -137,12 +138,13 @@ internal fun JavaType?.toConeKotlinTypeWithoutEnhancement( private fun JavaArrayType.toConeKotlinTypeWithoutEnhancement( session: FirSession, - javaTypeParameterStack: JavaTypeParameterStack + javaTypeParameterStack: JavaTypeParameterStack, + forAnnotationValueParameter: Boolean = false ): ConeFlexibleType { val componentType = componentType return if (componentType !is JavaPrimitiveType) { val classId = StandardClassIds.Array - val argumentType = componentType.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) + val argumentType = componentType.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack, forAnnotationValueParameter) classId.toConeFlexibleType( arrayOf(argumentType), typeArgumentsForUpper = arrayOf(ConeKotlinTypeProjectionOut(argumentType)) @@ -166,12 +168,24 @@ private fun ClassId.toConeFlexibleType( private fun JavaClassifierType.toConeKotlinTypeWithoutEnhancement( session: FirSession, javaTypeParameterStack: JavaTypeParameterStack, - forTypeParameterBounds: Boolean = false + forTypeParameterBounds: Boolean = false, + forAnnotationValueParameter: Boolean = false ): ConeKotlinType { - val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, isLowerBound = true, forTypeParameterBounds) + val lowerBound = toConeKotlinTypeForFlexibleBound( + session, + javaTypeParameterStack, + isLowerBound = true, + forTypeParameterBounds, + forAnnotationValueParameter = forAnnotationValueParameter + ) val upperBound = toConeKotlinTypeForFlexibleBound( - session, javaTypeParameterStack, isLowerBound = false, forTypeParameterBounds, lowerBound + session, + javaTypeParameterStack, + isLowerBound = false, + forTypeParameterBounds, + lowerBound, + forAnnotationValueParameter = forAnnotationValueParameter ) return if (isRaw) ConeRawType(lowerBound, upperBound) else ConeFlexibleType(lowerBound, upperBound) @@ -272,12 +286,17 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound( javaTypeParameterStack: JavaTypeParameterStack, isLowerBound: Boolean, forTypeParameterBounds: Boolean, - lowerBound: ConeLookupTagBasedType? = null + lowerBound: ConeLookupTagBasedType? = null, + forAnnotationValueParameter: Boolean = false ): ConeLookupTagBasedType { return when (val classifier = classifier) { is JavaClass -> { //val classId = classifier.classId!! - var classId = JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) ?: classifier.classId!! + var classId = if (forAnnotationValueParameter) { + JavaToKotlinClassMap.mapJavaToKotlinIncludingClassMapping(classifier.fqName!!) + } else { + JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!) + } ?: classifier.classId!! if (isLowerBound) { classId = classId.readOnlyToMutable() ?: classId diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt index 951aefe930e..c35e6bc0016 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/EnhancementSignatureParts.kt @@ -47,7 +47,8 @@ internal class EnhancementSignatureParts( internal fun enhance( session: FirSession, jsr305State: Jsr305State, - predefined: TypeEnhancementInfo? = null + predefined: TypeEnhancementInfo? = null, + forAnnotationValueParameter: Boolean = false ): PartEnhancementResult { val qualifiers = computeIndexedQualifiersForOverride(session, jsr305State) @@ -57,7 +58,11 @@ internal class EnhancementSignatureParts( } } - val typeWithoutEnhancement = current.type.toConeKotlinTypeWithoutEnhancement(session, javaTypeParameterStack) + val typeWithoutEnhancement = current.type.toConeKotlinTypeWithoutEnhancement( + session, + javaTypeParameterStack, + forAnnotationValueParameter + ) val containsFunctionN = typeWithoutEnhancement.contains { if (it is ConeClassErrorType) false else { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt index b4e66091d8d..04d5f5beb8b 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/SignatureEnhancement.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.fir.java.enhancement +import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession @@ -289,7 +290,12 @@ class FirSignatureEnhancement( parameterContainer = ownerParameter, methodContext = memberContext, typeInSignature = TypeInSignature.ValueParameter(hasReceiver, index) - ).enhance(session, jsr305State, predefinedEnhancementInfo?.parametersInfo?.getOrNull(index)) + ).enhance( + session, + jsr305State, + predefinedEnhancementInfo?.parametersInfo?.getOrNull(index), + forAnnotationValueParameter = owner.classKind == ClassKind.ANNOTATION_CLASS + ) val firResolvedTypeRef = signatureParts.type val defaultValueExpression = when (val defaultValue = ownerParameter.getDefaultValueFromAnnotation()) { NullDefaultValue -> buildConstExpression(null, FirConstKind.Null, null) diff --git a/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt b/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt index 1196a662c49..f3e631af95d 100644 --- a/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt +++ b/compiler/testData/codegen/box/reflection/annotations/classLiteralWithVoidDefault.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND_FIR: JVM_IR // WITH_REFLECT // TARGET_BACKEND: JVM // FILE: Anno.java diff --git a/compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.fir.kt b/compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.fir.kt index 76b97b9a5f2..df340589e70 100644 --- a/compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.fir.kt +++ b/compiler/testData/diagnostics/tests/annotations/deprecatedRepeatable.fir.kt @@ -2,9 +2,9 @@ import java.lang.annotation.Repeatable -@java.lang.annotation.Repeatable(Annotations::class) annotation class RepAnn +@java.lang.annotation.Repeatable(Annotations::class) annotation class RepAnn -@Repeatable(OtherAnnotations::class) annotation class OtherAnn +@Repeatable(OtherAnnotations::class) annotation class OtherAnn annotation class Annotations(vararg val value: RepAnn) diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArray.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArray.fir.kt index 6ce866b31de..a0bfa860b25 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArray.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArray.fir.kt @@ -12,11 +12,11 @@ public @interface A { @A(*arrayOf("5", "6"), "7", y = 3) fun test3() {} -@A("1", "2", "3", x = String::class, y = 4) fun test4() {} +@A("1", "2", "3", x = String::class, y = 4) fun test4() {} @A("4", y = 5) fun test5() {} -@A(*arrayOf("5", "6"), "7", x = Any::class, y = 6) fun test6() {} +@A(*arrayOf("5", "6"), "7", x = Any::class, y = 6) fun test6() {} @A(y = 7) fun test7() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.fir.kt index 65d5f8d36d7..28db1f988a1 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.fir.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/annotationParameters/valueArrayAndOtherDefault.fir.kt @@ -15,11 +15,11 @@ public @interface A { @A(*arrayOf("5", "6"), "7") fun test3() {} -@A("1", "2", "3", x = String::class) fun test4() {} +@A("1", "2", "3", x = String::class) fun test4() {} @A("4", y = 2) fun test5() {} -@A(*arrayOf("5", "6"), "7", x = Any::class, y = 3) fun test6() {} +@A(*arrayOf("5", "6"), "7", x = Any::class, y = 3) fun test6() {} @A() fun test7() {} @@ -27,4 +27,4 @@ public @interface A { @A(x = Any::class, *arrayOf("5", "6"), "7", y = 3) fun test9() {} @A(x = Any::class, value = ["5", "6"], "7", y = 3) fun test10() {} -@A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {} +@A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {} diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.fir.kt deleted file mode 100644 index cdfb16fc870..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.fir.kt +++ /dev/null @@ -1,19 +0,0 @@ -// FILE: A.java -public @interface A { - Class arg() default Integer.class; - int x() default 1; - B b(); -} - -// FILE: B.java -public @interface B { - Class arg() default String.class; - int y() default 2; -} - -// FILE: c.kt -@A(arg = String::class, b = B(y = 1)) class MyClass1 - -@A(b = B(y = 3)) class MyClass2 - -@A(arg = String::class, b = B(arg = Boolean::class)) class MyClass3 diff --git a/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.kt b/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.kt index 0eb01196673..501e72f7c3a 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/annotations/javaAnnotationsWithKClassParameter/annotationAsArgument.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // FILE: A.java public @interface A { Class arg() default Integer.class; diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JavaToKotlinClassMap.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JavaToKotlinClassMap.kt index 1718408c6f7..7f960b0dff3 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JavaToKotlinClassMap.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/builtins/jvm/JavaToKotlinClassMap.kt @@ -34,6 +34,8 @@ object JavaToKotlinClassMap : PlatformToKotlinClassMap { private val FUNCTION_N_CLASS_ID = ClassId.topLevel(FqName("kotlin.jvm.functions.FunctionN")) val FUNCTION_N_FQ_NAME = FUNCTION_N_CLASS_ID.asSingleFqName() private val K_FUNCTION_CLASS_ID = ClassId.topLevel(FqName("kotlin.reflect.KFunction")) + private val K_CLASS_CLASS_ID = ClassId.topLevel(FqName("kotlin.reflect.KClass")) + private val CLASS_CLASS_ID = classId(java.lang.Class::class.java) private val javaToKotlin = HashMap() private val kotlinToJava = HashMap() @@ -123,6 +125,11 @@ object JavaToKotlinClassMap : PlatformToKotlinClassMap { return javaToKotlin[fqName.toUnsafe()] } + fun mapJavaToKotlinIncludingClassMapping(fqName: FqName): ClassId? { + if (fqName == CLASS_CLASS_ID.asSingleFqName()) return K_CLASS_CLASS_ID + return mapJavaToKotlin(fqName) + } + fun mapJavaToKotlin(fqName: FqName, builtIns: KotlinBuiltIns, functionTypeArity: Int? = null): ClassDescriptor? { val kotlinClassId = if (functionTypeArity != null && fqName == FUNCTION_N_FQ_NAME) KotlinBuiltIns.getFunctionClassId(functionTypeArity)