[FIR] Support loading rxjava3 nullability annotations on bounded wildcards
^KT-53041 Fixed
This commit is contained in:
committed by
teamcity
parent
cb2dbca0c3
commit
7d945d9bdc
@@ -78,19 +78,31 @@ internal fun JavaType?.toFirResolvedTypeRef(
|
|||||||
|
|
||||||
private fun JavaType?.toConeKotlinType(
|
private fun JavaType?.toConeKotlinType(
|
||||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack,
|
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack,
|
||||||
mode: FirJavaTypeConversionMode
|
mode: FirJavaTypeConversionMode,
|
||||||
|
additionalAnnotations: Collection<JavaAnnotation>? = null
|
||||||
): ConeKotlinType =
|
): ConeKotlinType =
|
||||||
toConeTypeProjection(session, javaTypeParameterStack, Variance.INVARIANT, mode).type
|
toConeTypeProjection(session, javaTypeParameterStack, Variance.INVARIANT, mode, additionalAnnotations).type
|
||||||
?: StandardClassIds.Any.toConeFlexibleType(emptyArray(), emptyArray(), ConeAttributes.Empty)
|
?: StandardClassIds.Any.toConeFlexibleType(emptyArray(), emptyArray(), ConeAttributes.Empty)
|
||||||
|
|
||||||
private fun JavaType?.toConeTypeProjection(
|
private fun JavaType?.toConeTypeProjection(
|
||||||
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack,
|
session: FirSession, javaTypeParameterStack: JavaTypeParameterStack,
|
||||||
parameterVariance: Variance, mode: FirJavaTypeConversionMode
|
parameterVariance: Variance, mode: FirJavaTypeConversionMode,
|
||||||
|
additionalAnnotations: Collection<JavaAnnotation>? = null
|
||||||
): ConeTypeProjection {
|
): ConeTypeProjection {
|
||||||
val attributes = if (this != null && annotations.isNotEmpty())
|
val attributes = if (this != null && (annotations.isNotEmpty() || additionalAnnotations != null)) {
|
||||||
ConeAttributes.create(listOf(CustomAnnotationTypeAttribute(convertAnnotationsToFir(session, javaTypeParameterStack))))
|
val convertedAnnotations = buildList {
|
||||||
else
|
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
|
ConeAttributes.Empty
|
||||||
|
}
|
||||||
|
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is JavaClassifierType -> {
|
is JavaClassifierType -> {
|
||||||
@@ -141,7 +153,8 @@ private fun JavaType?.toConeTypeProjection(
|
|||||||
if (bound == null || (parameterVariance != Variance.INVARIANT && parameterVariance != argumentVariance)) {
|
if (bound == null || (parameterVariance != Variance.INVARIANT && parameterVariance != argumentVariance)) {
|
||||||
ConeStarProjection
|
ConeStarProjection
|
||||||
} else {
|
} 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)
|
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.resolve.transformers.body.resolve.expectedConeType
|
||||||
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef
|
||||||
import org.jetbrains.kotlin.fir.types.createArrayType
|
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.JavaClass
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaModifierListOwner
|
import org.jetbrains.kotlin.load.java.structure.JavaModifierListOwner
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.JavaWildcardType
|
||||||
import org.jetbrains.kotlin.types.ConstantValueKind
|
import org.jetbrains.kotlin.types.ConstantValueKind
|
||||||
|
|
||||||
internal val JavaModifierListOwner.modality: Modality
|
internal val JavaModifierListOwner.modality: Modality
|
||||||
@@ -98,3 +101,9 @@ private fun FirConstExpression<*>.setProperType(session: FirSession): FirConstEx
|
|||||||
replaceTypeRef(typeRef)
|
replaceTypeRef(typeRef)
|
||||||
return this
|
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 } }
|
||||||
|
}
|
||||||
|
|||||||
+1
@@ -1,5 +1,6 @@
|
|||||||
// FIR_IDENTICAL
|
// FIR_IDENTICAL
|
||||||
// JVM_TARGET: 1.8
|
// JVM_TARGET: 1.8
|
||||||
|
// TARGET_BACKEND: JVM
|
||||||
// NULLABILITY_ANNOTATIONS: @io.reactivex.rxjava3.annotations:strict
|
// NULLABILITY_ANNOTATIONS: @io.reactivex.rxjava3.annotations:strict
|
||||||
// IGNORE_LIGHT_ANALYSIS
|
// IGNORE_LIGHT_ANALYSIS
|
||||||
|
|
||||||
|
|||||||
-6
@@ -21140,12 +21140,6 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInTests() throws Exception {
|
public void testAllFilesPresentInTests() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestMetadata("kt53041.kt")
|
|
||||||
public void testKt53041() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests/kt53041.kt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-6
@@ -21104,12 +21104,6 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
|||||||
public void testAllFilesPresentInTests() throws Exception {
|
public void testAllFilesPresentInTests() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS_IR, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestMetadata("kt53041.kt")
|
|
||||||
public void testKt53041() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests/kt53041.kt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-5
@@ -18733,11 +18733,6 @@ public class IrCodegenBoxWasmTestGenerated extends AbstractIrCodegenBoxWasmTest
|
|||||||
public void testAllFilesPresentInTests() throws Exception {
|
public void testAllFilesPresentInTests() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^([^_](.+))\\.kt$"), null, TargetBackend.WASM, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@TestMetadata("kt53041.kt")
|
|
||||||
public void testKt53041() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests/kt53041.kt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-6
@@ -23789,12 +23789,6 @@ public class NativeCodegenBoxTestGenerated extends AbstractNativeCodegenBoxTest
|
|||||||
public void testAllFilesPresentInTests() throws Exception {
|
public void testAllFilesPresentInTests() throws Exception {
|
||||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.NATIVE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
@TestMetadata("kt53041.kt")
|
|
||||||
public void testKt53041() throws Exception {
|
|
||||||
runTest("compiler/testData/codegen/box/javaInterop/foreignAnnotationsTests/tests/kt53041.kt");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user