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 ff81f42d638..1d61b3a3473 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 @@ -18,6 +18,7 @@ import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType +import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers import org.jetbrains.kotlin.load.java.MUTABLE_ANNOTATIONS import org.jetbrains.kotlin.load.java.READ_ONLY_ANNOTATIONS import org.jetbrains.kotlin.load.java.structure.JavaClassifierType @@ -180,7 +181,7 @@ internal class EnhancementSignatureParts( private fun FirTypeRef?.extractQualifiersFromAnnotations( isHeadTypeConstructor: Boolean, - defaultQualifiersForType: JavaTypeQualifiers?, + defaultQualifiersForType: JavaDefaultQualifiers?, jsr305State: Jsr305State ): JavaTypeQualifiers { val composedAnnotation = @@ -204,10 +205,10 @@ internal class EnhancementSignatureParts( defaultQualifiersForType val nullabilityInfo = composedAnnotation.extractNullability(typeQualifierResolver, jsr305State) - ?: defaultTypeQualifier?.nullability?.let { nullability -> + ?: defaultTypeQualifier?.nullabilityQualifier?.let { nullability -> NullabilityQualifierWithMigrationStatus( - nullability, - defaultTypeQualifier.isNullabilityQualifierForWarning + nullability.qualifier, + nullability.isForWarningOnly ) } @@ -233,7 +234,7 @@ internal class EnhancementSignatureParts( private fun FirTypeRef?.computeQualifiersForOverride( session: FirSession, fromSupertypes: Collection, - defaultQualifiersForType: JavaTypeQualifiers?, + defaultQualifiersForType: JavaDefaultQualifiers?, isHeadTypeConstructor: Boolean, jsr305State: Jsr305State ): JavaTypeQualifiers { diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirAnnotationTypeQualifierResolver.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirAnnotationTypeQualifierResolver.kt index a1eaa5d2807..2a949fd12bf 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirAnnotationTypeQualifierResolver.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirAnnotationTypeQualifierResolver.kt @@ -63,15 +63,17 @@ class FirAnnotationTypeQualifierResolver(private val session: FirSession, privat return resolveTypeQualifierNickname(annotationClass) } - fun resolveQualifierBuiltInDefaultAnnotation(annotationCall: FirAnnotationCall): NullabilityQualifierWithApplicability? { + fun resolveQualifierBuiltInDefaultAnnotation(annotationCall: FirAnnotationCall): JavaDefaultQualifiers? { if (jsr305State.disabled) { return null } val annotationClassId = annotationCall.classId - return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATION_IDS[annotationClassId]?.let { (qualifier, applicability) -> + return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATION_IDS[annotationClassId]?.let { qualifierForDefaultingAnnotation -> val state = resolveJsr305ReportLevel(annotationCall).takeIf { it != ReportLevel.IGNORE } ?: return null - return NullabilityQualifierWithApplicability(qualifier.copy(isForWarningOnly = state.isWarning), applicability) + return qualifierForDefaultingAnnotation.copy( + nullabilityQualifier = qualifierForDefaultingAnnotation.nullabilityQualifier.copy(isForWarningOnly = state.isWarning) + ) } } diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirJavaEnhancementContext.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirJavaEnhancementContext.kt index 852840508a8..ccfdcd3b83e 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirJavaEnhancementContext.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/FirJavaEnhancementContext.kt @@ -26,7 +26,7 @@ fun extractDefaultNullabilityQualifier( typeQualifierResolver: FirAnnotationTypeQualifierResolver, jsr305State: Jsr305State, annotationCall: FirAnnotationCall -): NullabilityQualifierWithApplicability? { +): JavaDefaultQualifiers? { typeQualifierResolver.resolveQualifierBuiltInDefaultAnnotation(annotationCall)?.let { return it } val (typeQualifier, applicability) = @@ -45,7 +45,7 @@ fun extractDefaultNullabilityQualifier( typeQualifierResolver, jsr305State )?.copy(isForWarningOnly = jsr305ReportLevel.isWarning) ?: return null - return NullabilityQualifierWithApplicability(nullabilityQualifier, applicability) + return JavaDefaultQualifiers(nullabilityQualifier, applicability) } fun FirJavaEnhancementContext.computeNewDefaultTypeQualifiers( @@ -55,7 +55,7 @@ fun FirJavaEnhancementContext.computeNewDefaultTypeQualifiers( ): JavaTypeQualifiersByElementType? { if (typeQualifierResolver.disabled) return defaultTypeQualifiers - val nullabilityQualifiersWithApplicability = + val defaultQualifiers = additionalAnnotations.mapNotNull { annotationCall -> extractDefaultNullabilityQualifier( typeQualifierResolver, @@ -64,21 +64,21 @@ fun FirJavaEnhancementContext.computeNewDefaultTypeQualifiers( ) } - if (nullabilityQualifiersWithApplicability.isEmpty()) return defaultTypeQualifiers + if (defaultQualifiers.isEmpty()) return defaultTypeQualifiers - val nullabilityQualifiersByType = - defaultTypeQualifiers?.nullabilityQualifiers?.let(::QualifierByApplicabilityType) + val defaultQualifiersByType = + defaultTypeQualifiers?.defaultQualifiers?.let(::QualifierByApplicabilityType) ?: QualifierByApplicabilityType(AnnotationQualifierApplicabilityType::class.java) var wasUpdate = false - for ((nullability, applicableTo) in nullabilityQualifiersWithApplicability) { - for (applicabilityType in applicableTo) { - nullabilityQualifiersByType[applicabilityType] = nullability + for (qualifier in defaultQualifiers) { + for (applicabilityType in qualifier.qualifierApplicabilityTypes) { + defaultQualifiersByType[applicabilityType] = qualifier wasUpdate = true } } - return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(nullabilityQualifiersByType) + return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(defaultQualifiersByType) } fun FirJavaEnhancementContext.copyWithNewDefaultTypeQualifiers( diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt index 5bcbb9fa36b..10a980e944e 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/javaTypeUtils.kt @@ -13,6 +13,14 @@ import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.builder.buildConstExpression import org.jetbrains.kotlin.fir.expressions.builder.buildQualifiedAccessExpression +import org.jetbrains.kotlin.fir.declarations.FirCallableMemberDeclaration +import org.jetbrains.kotlin.fir.declarations.FirEnumEntry +import org.jetbrains.kotlin.fir.declarations.FirRegularClass +import org.jetbrains.kotlin.fir.declarations.FirValueParameter +import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall +import org.jetbrains.kotlin.fir.expressions.FirConstExpression +import org.jetbrains.kotlin.fir.expressions.FirExpression +import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.declarations.FirJavaClass import org.jetbrains.kotlin.fir.java.declarations.FirJavaField import org.jetbrains.kotlin.fir.references.builder.buildResolvedNamedReference @@ -25,6 +33,7 @@ import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.builder.buildResolvedTypeRef import org.jetbrains.kotlin.fir.types.jvm.FirJavaTypeRef +import org.jetbrains.kotlin.load.java.JavaDefaultQualifiers import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_NULL_FQ_NAME import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME import org.jetbrains.kotlin.load.java.descriptors.AnnotationDefaultValue @@ -243,7 +252,7 @@ private fun ConeClassifierLookupTag.enhanceMutability( internal data class TypeAndDefaultQualifiers( val type: FirTypeRef?, // null denotes '*' here - val defaultQualifiers: JavaTypeQualifiers? + val defaultQualifiers: JavaDefaultQualifiers? ) internal fun FirTypeRef.typeArguments(): List = diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt index b51c7066e73..0c7d1994744 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/AnnotationQualifiersFqNames.kt @@ -9,6 +9,11 @@ import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus import org.jetbrains.kotlin.name.FqName +data class JavaDefaultQualifiers( + val nullabilityQualifier: NullabilityQualifierWithMigrationStatus, + val qualifierApplicabilityTypes: Collection +) + val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname") val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier") val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierDefault") @@ -24,25 +29,25 @@ val DEFAULT_JSPECIFY_APPLICABILITY = listOf( val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( FqName("javax.annotation.ParametersAreNullableByDefault") to - NullabilityQualifierWithApplicability( + JavaDefaultQualifiers( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE), listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER) ), FqName("javax.annotation.ParametersAreNonnullByDefault") to - NullabilityQualifierWithApplicability( + JavaDefaultQualifiers( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), listOf(AnnotationQualifierApplicabilityType.VALUE_PARAMETER) ), - JSPECIFY_DEFAULT_NULLABLE to NullabilityQualifierWithApplicability( + JSPECIFY_DEFAULT_NULLABLE to JavaDefaultQualifiers( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE), DEFAULT_JSPECIFY_APPLICABILITY ), - JSPECIFY_DEFAULT_NOT_NULL to NullabilityQualifierWithApplicability( + JSPECIFY_DEFAULT_NOT_NULL to JavaDefaultQualifiers( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL), DEFAULT_JSPECIFY_APPLICABILITY ), - JSPECIFY_DEFAULT_NULLNESS_UNKNOWN to NullabilityQualifierWithApplicability( + JSPECIFY_DEFAULT_NULLNESS_UNKNOWN to JavaDefaultQualifiers( NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY), DEFAULT_JSPECIFY_APPLICABILITY ) diff --git a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JavaTypeQualifiersByElementType.kt b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JavaTypeQualifiersByElementType.kt index 4f4f9f18502..91e60078f03 100644 --- a/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JavaTypeQualifiersByElementType.kt +++ b/core/compiler.common.jvm/src/org/jetbrains/kotlin/load/java/JavaTypeQualifiersByElementType.kt @@ -5,20 +5,15 @@ package org.jetbrains.kotlin.load.java -import org.jetbrains.kotlin.load.java.typeEnhancement.JavaTypeQualifiers -import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus import java.util.* -typealias QualifierByApplicabilityType = EnumMap +typealias QualifierByApplicabilityType = + EnumMap -class JavaTypeQualifiersByElementType(val nullabilityQualifiers: QualifierByApplicabilityType) { - operator fun get(applicabilityType: AnnotationQualifierApplicabilityType?): JavaTypeQualifiers? { - val nullabilityQualifierWithMigrationStatus = nullabilityQualifiers[applicabilityType] ?: return null - - return JavaTypeQualifiers( - nullabilityQualifierWithMigrationStatus.qualifier, null, - isNotNullTypeParameter = false, - isNullabilityQualifierForWarning = nullabilityQualifierWithMigrationStatus.isForWarningOnly - ) +class JavaTypeQualifiersByElementType(val defaultQualifiers: QualifierByApplicabilityType) { + operator fun get( + applicabilityType: AnnotationQualifierApplicabilityType? + ): JavaDefaultQualifiers? { + return defaultQualifiers[applicabilityType] } -} +} \ No newline at end of file diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt index 9ddc52c62a7..0f5bdd0015f 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/AnnotationTypeQualifierResolver.kt @@ -78,14 +78,16 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager, private va return resolveTypeQualifierNickname(annotationClass) } - fun resolveQualifierBuiltInDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): NullabilityQualifierWithApplicability? { + fun resolveQualifierBuiltInDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): JavaDefaultQualifiers? { if (jsr305State.disabled) { return null } - return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationDescriptor.fqName]?.let { (qualifier, applicability) -> + return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationDescriptor.fqName]?.let { qualifierForDefaultingAnnotation -> val state = resolveJsr305AnnotationState(annotationDescriptor).takeIf { it != ReportLevel.IGNORE } ?: return null - return NullabilityQualifierWithApplicability(qualifier.copy(isForWarningOnly = state.isWarning), applicability) + return qualifierForDefaultingAnnotation.copy( + nullabilityQualifier = qualifierForDefaultingAnnotation.nullabilityQualifier.copy(isForWarningOnly = state.isWarning) + ) } } diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt index 9bc6141283c..948091b2a9b 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -31,6 +31,8 @@ import org.jetbrains.kotlin.load.java.components.SignaturePropagator import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeResolver import org.jetbrains.kotlin.load.java.sources.JavaSourceElementFactory import org.jetbrains.kotlin.load.java.structure.JavaTypeParameterListOwner +import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier +import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder @@ -39,6 +41,7 @@ import org.jetbrains.kotlin.resolve.sam.SamConversionResolver import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker +import java.util.* class JavaResolverComponents( val storageManager: StorageManager, @@ -129,29 +132,29 @@ fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers( ): JavaTypeQualifiersByElementType? { if (components.annotationTypeQualifierResolver.disabled) return defaultTypeQualifiers - val nullabilityQualifiersWithApplicability = + val defaultQualifiers = additionalAnnotations.mapNotNull(this::extractDefaultNullabilityQualifier) - if (nullabilityQualifiersWithApplicability.isEmpty()) return defaultTypeQualifiers + if (defaultQualifiers.isEmpty()) return defaultTypeQualifiers - val nullabilityQualifiersByType = - defaultTypeQualifiers?.nullabilityQualifiers?.let(::QualifierByApplicabilityType) + val defaultQualifiersByType = + defaultTypeQualifiers?.defaultQualifiers?.let(::QualifierByApplicabilityType) ?: QualifierByApplicabilityType(AnnotationQualifierApplicabilityType::class.java) var wasUpdate = false - for ((nullability, applicableTo) in nullabilityQualifiersWithApplicability) { - for (applicabilityType in applicableTo) { - nullabilityQualifiersByType[applicabilityType] = nullability + for (qualifier in defaultQualifiers) { + for (applicabilityType in qualifier.qualifierApplicabilityTypes) { + defaultQualifiersByType[applicabilityType] = qualifier wasUpdate = true } } - return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(nullabilityQualifiersByType) + return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(defaultQualifiersByType) } private fun LazyJavaResolverContext.extractDefaultNullabilityQualifier( annotationDescriptor: AnnotationDescriptor -): NullabilityQualifierWithApplicability? { +): JavaDefaultQualifiers? { val typeQualifierResolver = components.annotationTypeQualifierResolver typeQualifierResolver.resolveQualifierBuiltInDefaultAnnotation(annotationDescriptor)?.let { return it } @@ -173,7 +176,7 @@ private fun LazyJavaResolverContext.extractDefaultNullabilityQualifier( ?.copy(isForWarningOnly = jsr305State.isWarning) ?: return null - return NullabilityQualifierWithApplicability(nullabilityQualifier, applicability) + return JavaDefaultQualifiers(nullabilityQualifier, applicability) } fun LazyJavaResolverContext.replaceComponents( diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt index 2e5eb07a2a8..9b75711a1ed 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/java/typeEnhancement/signatureEnhancement.kt @@ -236,7 +236,7 @@ class SignatureEnhancement( return bounds.map { bound -> SignatureParts( typeParameter, bound, emptyList(), false, context, - AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_PARAMETER_BOUNDS, + AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS, typeParameterBounds = true ).enhance().type } @@ -258,7 +258,7 @@ class SignatureEnhancement( private val fromOverridden: Collection, private val isCovariant: Boolean, private val containerContext: LazyJavaResolverContext, - private val containerApplicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType, + private val containerApplicabilityType: AnnotationQualifierApplicabilityType, private val typeParameterBounds: Boolean = false ) { @@ -311,7 +311,7 @@ class SignatureEnhancement( private fun KotlinType.extractQualifiersFromAnnotations( isHeadTypeConstructor: Boolean, - defaultQualifiersForType: JavaTypeQualifiers? + defaultQualifiersForType: JavaDefaultQualifiers? ): JavaTypeQualifiers { val composedAnnotation = if (isHeadTypeConstructor && typeContainer != null) @@ -332,10 +332,10 @@ class SignatureEnhancement( val nullabilityInfo = composedAnnotation.extractNullability() - ?: defaultTypeQualifier?.nullability?.let { + ?: defaultTypeQualifier?.nullabilityQualifier?.let { nullabilityQualifierWithMigrationStatus -> NullabilityQualifierWithMigrationStatus( - defaultTypeQualifier.nullability!!, - defaultTypeQualifier.isNullabilityQualifierForWarning + nullabilityQualifierWithMigrationStatus.qualifier, + nullabilityQualifierWithMigrationStatus.isForWarningOnly ) } @@ -397,9 +397,9 @@ class SignatureEnhancement( c.defaultTypeQualifiers ?.get( if (typeParameterBounds) - AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_PARAMETER_BOUNDS + AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS else - AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_USE + AnnotationQualifierApplicabilityType.TYPE_USE ) ) ) @@ -420,7 +420,7 @@ class SignatureEnhancement( private fun KotlinType.computeQualifiersForOverride( fromSupertypes: Collection, - defaultQualifiersForType: JavaTypeQualifiers?, + defaultQualifiersForType: JavaDefaultQualifiers?, isHeadTypeConstructor: Boolean ): JavaTypeQualifiers { val superQualifiers = fromSupertypes.map { it.extractQualifiers() } @@ -514,5 +514,5 @@ class SignatureEnhancement( private data class TypeAndDefaultQualifiers( val type: KotlinType, - val defaultQualifiers: JavaTypeQualifiers? + val defaultQualifiers: JavaDefaultQualifiers? )