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 fd981dbe72f..2a904092477 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 @@ -10,7 +10,7 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer import org.jetbrains.kotlin.fir.FirSession import org.jetbrains.kotlin.fir.declarations.FirValueParameter import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.expressions.resolvedFqName +import org.jetbrains.kotlin.fir.expressions.classId import org.jetbrains.kotlin.fir.java.JavaTypeParameterStack import org.jetbrains.kotlin.fir.java.toConeKotlinTypeWithNullability import org.jetbrains.kotlin.fir.java.toFirJavaTypeRef @@ -23,7 +23,7 @@ import org.jetbrains.kotlin.load.java.MUTABLE_ANNOTATIONS import org.jetbrains.kotlin.load.java.READ_ONLY_ANNOTATIONS import org.jetbrains.kotlin.load.java.structure.JavaWildcardType import org.jetbrains.kotlin.load.java.typeEnhancement.* -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.utils.Jsr305State import org.jetbrains.kotlin.utils.addToStdlib.safeAs @@ -179,9 +179,9 @@ internal class EnhancementSignatureParts( else this?.annotations.orEmpty() - fun List.ifPresent(qualifier: T) = - if (any { fqName -> - composedAnnotation.any { it.resolvedFqName == fqName } + fun List.ifPresent(qualifier: T) = + if (any { classId -> + composedAnnotation.any { it.classId == classId } } ) qualifier else null @@ -205,10 +205,10 @@ internal class EnhancementSignatureParts( return JavaTypeQualifiers( nullabilityInfo?.qualifier, uniqueNotNull( - READ_ONLY_ANNOTATIONS.ifPresent( + READ_ONLY_ANNOTATION_IDS.ifPresent( MutabilityQualifier.READ_ONLY ), - MUTABLE_ANNOTATIONS.ifPresent( + MUTABLE_ANNOTATION_IDS.ifPresent( MutabilityQualifier.MUTABLE ) ), @@ -297,5 +297,10 @@ internal class EnhancementSignatureParts( val wereChanges: Boolean, val containsFunctionN: Boolean ) + + companion object { + private val READ_ONLY_ANNOTATION_IDS = READ_ONLY_ANNOTATIONS.map { ClassId.topLevel(it) } + private val MUTABLE_ANNOTATION_IDS = MUTABLE_ANNOTATIONS.map { ClassId.topLevel(it) } + } } 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 02492c144b8..9cd8816cba2 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 @@ -12,7 +12,9 @@ import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirClassSymbol import org.jetbrains.kotlin.load.java.* +import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME import org.jetbrains.kotlin.load.java.lazy.NullabilityQualifierWithApplicability +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.utils.Jsr305State import org.jetbrains.kotlin.utils.ReportLevel import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult @@ -37,7 +39,7 @@ class FirAnnotationTypeQualifierResolver(private val session: FirSession, privat // TODO: memoize this function private fun computeTypeQualifierNickname(klass: FirRegularClass): FirAnnotationCall? { - if (klass.annotations.none { it.resolvedFqName == TYPE_QUALIFIER_NICKNAME_FQNAME }) return null + if (klass.annotations.none { it.classId == TYPE_QUALIFIER_NICKNAME_ID }) return null return klass.annotations.firstNotNullResult(this::resolveTypeQualifierAnnotation) } @@ -67,7 +69,8 @@ class FirAnnotationTypeQualifierResolver(private val session: FirSession, privat return null } - return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationCall.resolvedFqName]?.let { (qualifier, applicability) -> + val annotationClassId = annotationCall.classId + return BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATION_IDS[annotationClassId]?.let { (qualifier, applicability) -> val state = resolveJsr305ReportLevel(annotationCall).takeIf { it != ReportLevel.IGNORE } ?: return null return NullabilityQualifierWithApplicability(qualifier.copy(isForWarningOnly = state.isWarning), applicability) } @@ -80,15 +83,15 @@ class FirAnnotationTypeQualifierResolver(private val session: FirSession, privat val typeQualifierDefaultAnnotatedClass = annotationCall.resolvedClass?.takeIf { klass -> - klass.annotations.any { it.resolvedFqName == TYPE_QUALIFIER_DEFAULT_FQNAME } + klass.annotations.any { it.classId == TYPE_QUALIFIER_DEFAULT_ID } } ?: return null val elementTypesMask = annotationCall.resolvedClass!! - .annotations.find { it.resolvedFqName == TYPE_QUALIFIER_DEFAULT_FQNAME }!! + .annotations.find { it.classId == TYPE_QUALIFIER_DEFAULT_ID }!! .arguments .flatMap { argument -> - if (argument !is FirNamedArgumentExpression || argument.name == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME) + if (argument !is FirNamedArgumentExpression || argument.name == DEFAULT_ANNOTATION_MEMBER_NAME) argument.mapConstantToQualifierApplicabilityTypes() else emptyList() @@ -110,13 +113,13 @@ class FirAnnotationTypeQualifierResolver(private val session: FirSession, privat } fun resolveJsr305CustomLevel(annotationCall: FirAnnotationCall): ReportLevel? { - jsr305State.user[annotationCall.resolvedFqName?.asString()]?.let { return it } + jsr305State.user[annotationCall.classId?.run { packageFqName.asString() + "." + relativeClassName.asString() }]?.let { return it } return annotationCall.resolvedClass?.migrationAnnotationStatus() } private fun FirRegularClass.migrationAnnotationStatus(): ReportLevel? { val enumEntryName = annotations.find { - it.resolvedFqName == MIGRATION_ANNOTATION_FQNAME + it.classId == MIGRATION_ANNOTATION_ID }?.arguments?.firstOrNull()?.toResolvedCallableSymbol()?.callableId?.callableName ?: return null jsr305State.migration?.let { return it } @@ -148,5 +151,14 @@ class FirAnnotationTypeQualifierResolver(private val session: FirSession, privat } private val FirRegularClass.isAnnotatedWithTypeQualifier: Boolean - get() = this.symbol.classId.asSingleFqName() in BUILT_IN_TYPE_QUALIFIER_FQ_NAMES || - annotations.any { it.resolvedFqName == TYPE_QUALIFIER_FQNAME } + get() = this.symbol.classId in BUILT_IN_TYPE_QUALIFIER_IDS || + annotations.any { it.classId == TYPE_QUALIFIER_ID } + +private val TYPE_QUALIFIER_ID = ClassId.topLevel(TYPE_QUALIFIER_FQNAME) +private val BUILT_IN_TYPE_QUALIFIER_IDS = BUILT_IN_TYPE_QUALIFIER_FQ_NAMES.map { ClassId.topLevel(it) } +private val TYPE_QUALIFIER_DEFAULT_ID = ClassId.topLevel(TYPE_QUALIFIER_DEFAULT_FQNAME) +private val MIGRATION_ANNOTATION_ID = ClassId.topLevel(MIGRATION_ANNOTATION_FQNAME) +private val TYPE_QUALIFIER_NICKNAME_ID = ClassId.topLevel(TYPE_QUALIFIER_NICKNAME_FQNAME) + +private val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATION_IDS = + BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS.mapKeys { ClassId.topLevel(it.key) } \ No newline at end of file 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 02f61646c70..3d66dfa2766 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 @@ -31,7 +31,8 @@ import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.impl.FirResolvedTypeRefImpl import org.jetbrains.kotlin.ir.expressions.IrConstKind -import org.jetbrains.kotlin.load.java.JvmAnnotationNames +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 import org.jetbrains.kotlin.load.java.descriptors.NullDefaultValue import org.jetbrains.kotlin.load.java.descriptors.StringDefaultValue @@ -288,15 +289,18 @@ internal fun ConeKotlinType.lexicalCastFrom(session: FirSession, value: String): } internal fun FirValueParameter.getDefaultValueFromAnnotation(): AnnotationDefaultValue? { - annotations.find { it.resolvedFqName == JvmAnnotationNames.DEFAULT_VALUE_FQ_NAME } + annotations.find { it.classId == DEFAULT_VALUE_ID } ?.arguments?.firstOrNull() ?.safeAs>()?.value?.safeAs() ?.let { return StringDefaultValue(it) } - if (annotations.any { it.resolvedFqName == JvmAnnotationNames.DEFAULT_NULL_FQ_NAME }) { + if (annotations.any { it.classId == DEFAULT_NULL_ID }) { return NullDefaultValue } return null } +private val DEFAULT_VALUE_ID = ClassId.topLevel(DEFAULT_VALUE_FQ_NAME) +private val DEFAULT_NULL_ID = ClassId.topLevel(DEFAULT_NULL_FQ_NAME) + diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/nullabilityUtils.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/nullabilityUtils.kt index 97c07ae1500..2bd4f714f12 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/nullabilityUtils.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/enhancement/nullabilityUtils.kt @@ -6,11 +6,12 @@ package org.jetbrains.kotlin.fir.java.enhancement import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall -import org.jetbrains.kotlin.fir.expressions.resolvedFqName +import org.jetbrains.kotlin.fir.expressions.classId import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol import org.jetbrains.kotlin.load.java.* import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifierWithMigrationStatus +import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.utils.Jsr305State import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult @@ -40,25 +41,25 @@ fun FirAnnotationCall.extractNullability( } private fun FirAnnotationCall.extractNullabilityFromKnownAnnotations(jsr305State: Jsr305State): NullabilityQualifierWithMigrationStatus? { - val annotationFqName = resolvedFqName ?: return null + val annotationClassId = classId ?: return null return when { - annotationFqName in NULLABLE_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) - annotationFqName in NOT_NULL_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) - annotationFqName == JAVAX_NONNULL_ANNOTATION -> extractNullabilityTypeFromArgument() + annotationClassId in NULLABLE_ANNOTATION_IDS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) + annotationClassId in NOT_NULL_ANNOTATION_IDS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) + annotationClassId == JAVAX_NONNULL_ANNOTATION_ID -> extractNullabilityTypeFromArgument() - annotationFqName == COMPATQUAL_NULLABLE_ANNOTATION && jsr305State.enableCompatqualCheckerFrameworkAnnotations -> + annotationClassId == COMPATQUAL_NULLABLE_ANNOTATION_ID && jsr305State.enableCompatqualCheckerFrameworkAnnotations -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE) - annotationFqName == COMPATQUAL_NONNULL_ANNOTATION && jsr305State.enableCompatqualCheckerFrameworkAnnotations -> + annotationClassId == COMPATQUAL_NONNULL_ANNOTATION_ID && jsr305State.enableCompatqualCheckerFrameworkAnnotations -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) - annotationFqName == ANDROIDX_RECENTLY_NON_NULL_ANNOTATION -> NullabilityQualifierWithMigrationStatus( + annotationClassId == ANDROIDX_RECENTLY_NON_NULL_ANNOTATION_ID -> NullabilityQualifierWithMigrationStatus( NullabilityQualifier.NOT_NULL, isForWarningOnly = true ) - annotationFqName == ANDROIDX_RECENTLY_NULLABLE_ANNOTATION -> NullabilityQualifierWithMigrationStatus( + annotationClassId == ANDROIDX_RECENTLY_NULLABLE_ANNOTATION_ID -> NullabilityQualifierWithMigrationStatus( NullabilityQualifier.NULLABLE, isForWarningOnly = true ) @@ -78,3 +79,11 @@ private fun FirAnnotationCall.extractNullabilityTypeFromArgument(): NullabilityQ else -> null } } + +private val NULLABLE_ANNOTATION_IDS = NULLABLE_ANNOTATIONS.map { ClassId.topLevel(it) } +private val NOT_NULL_ANNOTATION_IDS = NOT_NULL_ANNOTATIONS.map { ClassId.topLevel(it) } +private val JAVAX_NONNULL_ANNOTATION_ID = ClassId.topLevel(JAVAX_NONNULL_ANNOTATION) +private val COMPATQUAL_NULLABLE_ANNOTATION_ID = ClassId.topLevel(COMPATQUAL_NULLABLE_ANNOTATION) +private val COMPATQUAL_NONNULL_ANNOTATION_ID = ClassId.topLevel(COMPATQUAL_NONNULL_ANNOTATION) +private val ANDROIDX_RECENTLY_NON_NULL_ANNOTATION_ID = ClassId.topLevel(ANDROIDX_RECENTLY_NON_NULL_ANNOTATION) +private val ANDROIDX_RECENTLY_NULLABLE_ANNOTATION_ID = ClassId.topLevel(ANDROIDX_RECENTLY_NULLABLE_ANNOTATION) diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt index 9abd28de594..23c67eca811 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/expressions/FirExpressionUtil.kt @@ -6,7 +6,6 @@ package org.jetbrains.kotlin.fir.expressions import com.intellij.psi.PsiElement -import org.jetbrains.kotlin.fir.declarations.FirRegularClass import org.jetbrains.kotlin.fir.expressions.impl.FirConstExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirErrorExpressionImpl import org.jetbrains.kotlin.fir.expressions.impl.FirErrorLoop @@ -16,13 +15,13 @@ import org.jetbrains.kotlin.fir.types.ConeClassErrorType import org.jetbrains.kotlin.fir.types.ConeClassLikeType import org.jetbrains.kotlin.fir.types.FirResolvedTypeRef import org.jetbrains.kotlin.ir.expressions.IrConstKind -import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.ClassId inline val FirAnnotationCall.coneClassLikeType: ConeClassLikeType? get() = ((annotationTypeRef as? FirResolvedTypeRef)?.type as? ConeClassLikeType)?.takeIf { it !is ConeClassErrorType } -inline val FirAnnotationCall.resolvedFqName: FqName? - get() = coneClassLikeType?.lookupTag?.classId?.asSingleFqName() +inline val FirAnnotationCall.classId: ClassId? + get() = coneClassLikeType?.lookupTag?.classId fun FirConstExpressionImpl(psi: PsiElement?, kind: IrConstKind, value: T?, errorReason: String): FirExpression = value?.let { FirConstExpressionImpl(psi, kind, it) } ?: FirErrorExpressionImpl(psi, errorReason)