K2 Java: fix 'value' annotation constructor parameter type to Array<out>

#KT-61100 Fixed
This commit is contained in:
Mikhail Glukhikh
2023-10-11 14:55:54 +02:00
committed by Space Team
parent 8e4a6759a4
commit af58b30e5f
7 changed files with 33 additions and 21 deletions
@@ -16,13 +16,11 @@ import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
import org.jetbrains.kotlin.fir.types.jvm.buildJavaTypeRef
import org.jetbrains.kotlin.fir.utils.exceptions.withConeTypeEntry
import org.jetbrains.kotlin.load.java.structure.*
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.StandardClassIds
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.addToStdlib.runUnless
import org.jetbrains.kotlin.utils.exceptions.errorWithAttachment
private fun ClassId.toConeFlexibleType(
@@ -37,8 +35,10 @@ private fun ClassId.toConeFlexibleType(
}
enum class FirJavaTypeConversionMode {
DEFAULT, ANNOTATION_MEMBER, SUPERTYPE,
TYPE_PARAMETER_BOUND_FIRST_ROUND, TYPE_PARAMETER_BOUND_AFTER_FIRST_ROUND
DEFAULT, ANNOTATION_MEMBER, ANNOTATION_CONSTRUCTOR_PARAMETER, SUPERTYPE,
TYPE_PARAMETER_BOUND_FIRST_ROUND, TYPE_PARAMETER_BOUND_AFTER_FIRST_ROUND;
val insideAnnotation: Boolean get() = this == ANNOTATION_MEMBER || this == ANNOTATION_CONSTRUCTOR_PARAMETER
}
fun FirTypeRef.resolveIfJavaType(
@@ -105,7 +105,7 @@ private fun JavaType?.toConeTypeProjection(
return when (this) {
is JavaClassifierType -> {
val lowerBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, mode, attributes)
if (mode == FirJavaTypeConversionMode.ANNOTATION_MEMBER) {
if (mode.insideAnnotation) {
return lowerBound
}
val upperBound = toConeKotlinTypeForFlexibleBound(session, javaTypeParameterStack, mode, attributes, lowerBound)
@@ -133,11 +133,14 @@ private fun JavaType?.toConeTypeProjection(
else ->
StandardClassIds.Array to arrayOf(componentType.toConeKotlinType(session, javaTypeParameterStack, mode))
}
if (mode == FirJavaTypeConversionMode.ANNOTATION_MEMBER) {
classId.constructClassLikeType(arguments, isNullable = false, attributes)
} else {
val argumentsForUpper = Array(arguments.size) { ConeKotlinTypeProjectionOut(arguments[it]) }
classId.toConeFlexibleType(arguments, argumentsForUpper, attributes)
val argumentsWithOutProjection = Array(arguments.size) { ConeKotlinTypeProjectionOut(arguments[it]) }
when (mode) {
FirJavaTypeConversionMode.ANNOTATION_CONSTRUCTOR_PARAMETER ->
classId.constructClassLikeType(argumentsWithOutProjection, isNullable = false, attributes)
FirJavaTypeConversionMode.ANNOTATION_MEMBER ->
classId.constructClassLikeType(arguments, isNullable = false, attributes)
else ->
classId.toConeFlexibleType(arguments, typeArgumentsForUpper = argumentsWithOutProjection, attributes)
}
}
@@ -175,7 +178,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
): ConeLookupTagBasedType {
return when (val classifier = classifier) {
is JavaClass -> {
var classId = if (mode == FirJavaTypeConversionMode.ANNOTATION_MEMBER) {
var classId = if (mode.insideAnnotation) {
JavaToKotlinClassMap.mapJavaToKotlinIncludingClassMapping(classifier.fqName!!)
} else {
JavaToKotlinClassMap.mapJavaToKotlin(classifier.fqName!!)
@@ -195,8 +198,8 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
lookupTag.takeIf { lowerBound == null && mode != FirJavaTypeConversionMode.TYPE_PARAMETER_BOUND_FIRST_ROUND }
?.toFirRegularClassSymbol(session)?.typeParameterSymbols
// Given `C<T : X>`, `C` -> `C<X>..C<*>?`.
when (mode) {
FirJavaTypeConversionMode.ANNOTATION_MEMBER -> Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
when {
mode.insideAnnotation -> Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
else -> typeParameterSymbols?.getProjectionsForRawType(session)
?: Array(classifier.allTypeParametersNumber()) { ConeStarProjection }
}
@@ -208,7 +211,7 @@ private fun JavaClassifierType.toConeKotlinTypeForFlexibleBound(
?.toFirRegularClassSymbol(session)?.typeParameterSymbols
Array(typeArguments.size) { index ->
// TODO: check this
val newMode = if (mode == FirJavaTypeConversionMode.ANNOTATION_MEMBER) FirJavaTypeConversionMode.DEFAULT else mode
val newMode = if (mode.insideAnnotation) FirJavaTypeConversionMode.DEFAULT else mode
val argument = typeArguments[index]
val variance = typeParameterSymbols?.getOrNull(index)?.fir?.variance ?: Variance.INVARIANT
argument.toConeTypeProjection(session, javaTypeParameterStack, variance, newMode)
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.fir.java.enhancement
import org.jetbrains.kotlin.KtFakeSourceElementKind
import org.jetbrains.kotlin.builtins.StandardNames.DEFAULT_VALUE_PARAMETER
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fakeElement
@@ -43,6 +44,7 @@ import org.jetbrains.kotlin.fir.types.impl.ConeTypeParameterTypeImpl
import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef
import org.jetbrains.kotlin.fir.utils.exceptions.withFirEntry
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType.VALUE_PARAMETER
import org.jetbrains.kotlin.load.java.FakePureImplementationsProvider
import org.jetbrains.kotlin.load.java.JavaTypeQualifiersByElementType
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
@@ -647,7 +649,7 @@ class FirSignatureEnhancement(
parameterContainer?.let {
typeQualifierResolver.extractAndMergeDefaultQualifiers(defaultQualifiers, it.annotations)
} ?: defaultQualifiers,
AnnotationQualifierApplicabilityType.VALUE_PARAMETER,
VALUE_PARAMETER,
typeInSignature,
predefined,
forAnnotationMember
@@ -665,7 +667,14 @@ class FirSignatureEnhancement(
): FirResolvedTypeRef {
val typeRef = typeInSignature.getTypeRef(this)
val typeRefsFromOverridden = overriddenMembers.map { typeInSignature.getTypeRef(it) }
val mode = if (forAnnotationMember) FirJavaTypeConversionMode.ANNOTATION_MEMBER else FirJavaTypeConversionMode.DEFAULT
val mode = when {
!forAnnotationMember ->
FirJavaTypeConversionMode.DEFAULT
containerApplicabilityType == VALUE_PARAMETER && (typeContainer as? FirValueParameter)?.name == DEFAULT_VALUE_PARAMETER ->
FirJavaTypeConversionMode.ANNOTATION_CONSTRUCTOR_PARAMETER
else ->
FirJavaTypeConversionMode.ANNOTATION_MEMBER
}
return EnhancementSignatureParts(
session, typeQualifierResolver, typeContainer, isCovariant, forceOnlyHeadTypeConstructor = false,
containerApplicabilityType, containerQualifiers