FIR Java enhancement: get rid of FirAnnotationCall.resolvedFqName
This commit is contained in:
+12
-7
@@ -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 <T : Any> List<FqName>.ifPresent(qualifier: T) =
|
||||
if (any { fqName ->
|
||||
composedAnnotation.any { it.resolvedFqName == fqName }
|
||||
fun <T : Any> List<ClassId>.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) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+21
-9
@@ -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) }
|
||||
@@ -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<FirConstExpression<*>>()?.value?.safeAs<String>()
|
||||
?.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)
|
||||
|
||||
|
||||
+18
-9
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user