[FIR] Support loading rxjava3 nullability annotations on bounded wildcards

^KT-53041 Fixed
This commit is contained in:
Victor Petukhov
2022-07-05 15:36:31 +02:00
committed by teamcity
parent cb2dbca0c3
commit 7d945d9bdc
7 changed files with 30 additions and 30 deletions
@@ -78,19 +78,31 @@ internal fun JavaType?.toFirResolvedTypeRef(
private fun JavaType?.toConeKotlinType(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack,
mode: FirJavaTypeConversionMode
mode: FirJavaTypeConversionMode,
additionalAnnotations: Collection<JavaAnnotation>? = null
): ConeKotlinType =
toConeTypeProjection(session, javaTypeParameterStack, Variance.INVARIANT, mode).type
toConeTypeProjection(session, javaTypeParameterStack, Variance.INVARIANT, mode, additionalAnnotations).type
?: StandardClassIds.Any.toConeFlexibleType(emptyArray(), emptyArray(), ConeAttributes.Empty)
private fun JavaType?.toConeTypeProjection(
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack,
parameterVariance: Variance, mode: FirJavaTypeConversionMode
parameterVariance: Variance, mode: FirJavaTypeConversionMode,
additionalAnnotations: Collection<JavaAnnotation>? = null
): ConeTypeProjection {
val attributes = if (this != null && annotations.isNotEmpty())
ConeAttributes.create(listOf(CustomAnnotationTypeAttribute(convertAnnotationsToFir(session, javaTypeParameterStack))))
else
val attributes = if (this != null && (annotations.isNotEmpty() || additionalAnnotations != null)) {
val convertedAnnotations = buildList {
if (annotations.isNotEmpty()) {
addAll(this@toConeTypeProjection.convertAnnotationsToFir(session, javaTypeParameterStack))
}
if (additionalAnnotations != null) {
addAll(additionalAnnotations.convertAnnotationsToFir(session, javaTypeParameterStack))
}
}
ConeAttributes.create(listOf(CustomAnnotationTypeAttribute(convertedAnnotations)))
} else {
ConeAttributes.Empty
}
return when (this) {
is JavaClassifierType -> {
@@ -141,7 +153,8 @@ private fun JavaType?.toConeTypeProjection(
if (bound == null || (parameterVariance != Variance.INVARIANT && parameterVariance != argumentVariance)) {
ConeStarProjection
} else {
val boundType = bound.toConeKotlinType(session, javaTypeParameterStack, mode)
val nullabilityAnnotationOnWildcard = extractNullabilityAnnotationOnBoundedWildcard(this)?.let(::listOf)
val boundType = bound.toConeKotlinType(session, javaTypeParameterStack, mode, nullabilityAnnotationOnWildcard)
if (isExtends) ConeKotlinTypeProjectionOut(boundType) else ConeKotlinTypeProjectionIn(boundType)
}
}
@@ -20,8 +20,11 @@ import org.jetbrains.kotlin.fir.expressions.builder.buildErrorExpression
import org.jetbrains.kotlin.fir.resolve.transformers.body.resolve.expectedConeType
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
import org.jetbrains.kotlin.fir.types.createArrayType
import org.jetbrains.kotlin.load.java.RXJAVA3_ANNOTATIONS
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaModifierListOwner
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
import org.jetbrains.kotlin.types.ConstantValueKind
internal val JavaModifierListOwner.modality: Modality
@@ -98,3 +101,9 @@ private fun FirConstExpression<*>.setProperType(session: FirSession): FirConstEx
replaceTypeRef(typeRef)
return this
}
// For now, it's supported only for RxJava3 annotations, see KT-53041
fun extractNullabilityAnnotationOnBoundedWildcard(wildcardType: JavaWildcardType): JavaAnnotation? {
require(wildcardType.bound != null) { "Nullability annotations on unbounded wildcards aren't supported" }
return wildcardType.annotations.find { annotation -> RXJAVA3_ANNOTATIONS.any { annotation.classId?.asSingleFqName() == it } }
}