Put type enhancement improvements under the compiler flag

This commit is contained in:
Victor Petukhov
2020-12-09 12:16:26 +03:00
parent 857cc92326
commit 6f8f531d87
30 changed files with 274 additions and 50 deletions
@@ -25,10 +25,11 @@ import org.jetbrains.kotlin.name.FqName
class LazyJavaAnnotations(
private val c: LazyJavaResolverContext,
private val annotationOwner: JavaAnnotationOwner
private val annotationOwner: JavaAnnotationOwner,
private val areAnnotationsFreshlySupported: Boolean = false
) : Annotations {
private val annotationDescriptors = c.components.storageManager.createMemoizedFunctionWithNullableValues { annotation: JavaAnnotation ->
JavaAnnotationMapper.mapOrResolveJavaAnnotation(annotation, c)
JavaAnnotationMapper.mapOrResolveJavaAnnotation(annotation, c, areAnnotationsFreshlySupported)
}
override fun findAnnotation(fqName: FqName) =
@@ -31,8 +31,6 @@ 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
@@ -42,7 +40,6 @@ import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import org.jetbrains.kotlin.utils.JavaTypeEnhancementState
import java.util.*
class JavaResolverComponents(
val storageManager: StorageManager,
@@ -84,6 +81,7 @@ class JavaResolverComponents(
interface JavaResolverSettings {
val isReleaseCoroutines: Boolean
val correctNullabilityForNotNullTypeParameter: Boolean
val enhancementImprovements: Boolean
object Default : JavaResolverSettings {
override val isReleaseCoroutines: Boolean
@@ -91,16 +89,21 @@ interface JavaResolverSettings {
override val correctNullabilityForNotNullTypeParameter: Boolean
get() = false
override val enhancementImprovements: Boolean
get() = false
}
companion object {
fun create(
isReleaseCoroutines: Boolean,
correctNullabilityForNotNullTypeParameter: Boolean
correctNullabilityForNotNullTypeParameter: Boolean,
enhancementImprovements: Boolean,
): JavaResolverSettings =
object : JavaResolverSettings {
override val isReleaseCoroutines get() = isReleaseCoroutines
override val correctNullabilityForNotNullTypeParameter get() = correctNullabilityForNotNullTypeParameter
override val enhancementImprovements get() = enhancementImprovements
}
}
}
@@ -172,9 +175,11 @@ private fun LazyJavaResolverContext.extractDefaultNullabilityQualifier(
return null
}
val areImprovementsEnabled = components.settings.typeEnhancementImprovements
val nullabilityQualifier =
components.signatureEnhancement.extractNullability(typeQualifier)?.copy(isForWarningOnly = jsr305State.isWarning)
?: return null
components.signatureEnhancement.extractNullability(typeQualifier, areImprovementsEnabled, typeParameterBounds = false)
?.copy(isForWarningOnly = jsr305State.isWarning) ?: return null
return JavaDefaultQualifiers(nullabilityQualifier, applicability)
}
@@ -208,7 +208,11 @@ class LazyJavaClassDescriptor(
for (javaType in javaTypes) {
val kotlinType = c.typeResolver.transformJavaType(javaType, TypeUsage.SUPERTYPE.toAttributes())
val enhancedKotlinType = c.components.signatureEnhancement.enhanceSuperType(kotlinType, c)
val areImprovementsEnabled = c.components.settings.typeEnhancementImprovements
val enhancedKotlinType = if (areImprovementsEnabled) {
c.components.signatureEnhancement.enhanceSuperType(kotlinType, c)
} else kotlinType
if (enhancedKotlinType.constructor.declarationDescriptor is NotFoundClasses.MockClassDescriptor) {
incomplete.add(javaType)
}
@@ -62,7 +62,7 @@ class JavaTypeResolver(
fun transformArrayType(arrayType: JavaArrayType, attr: JavaTypeAttributes, isVararg: Boolean = false): KotlinType {
val javaComponentType = arrayType.componentType
val primitiveType = (javaComponentType as? JavaPrimitiveType)?.type
val annotations = LazyJavaAnnotations(c, arrayType)
val annotations = LazyJavaAnnotations(c, arrayType, areAnnotationsFreshlySupported = true)
if (primitiveType != null) {
val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType)
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.load.java.*
import org.jetbrains.kotlin.load.java.descriptors.*
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.copyWithNewDefaultTypeQualifiers
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaAnnotationDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaTypeParameterDescriptor
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
@@ -52,21 +53,25 @@ class SignatureEnhancement(
private val typeEnhancement: JavaTypeEnhancement
) {
private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? {
private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(isForWarningOnly: Boolean): NullabilityQualifierWithMigrationStatus? {
val enumValue = firstArgument() as? EnumValue
// if no argument is specified, use default value: NOT_NULL
?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
return when (enumValue.enumEntryName.asString()) {
"ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
"MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
"UNKNOWN" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY)
"ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
"MAYBE", "NEVER" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
"UNKNOWN" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.FORCE_FLEXIBILITY, isForWarningOnly)
else -> null
}
}
fun extractNullability(annotationDescriptor: AnnotationDescriptor): NullabilityQualifierWithMigrationStatus? {
extractNullabilityFromKnownAnnotations(annotationDescriptor)?.let { return it }
fun extractNullability(
annotationDescriptor: AnnotationDescriptor,
areImprovementsEnabled: Boolean,
typeParameterBounds: Boolean
): NullabilityQualifierWithMigrationStatus? {
extractNullabilityFromKnownAnnotations(annotationDescriptor, areImprovementsEnabled, typeParameterBounds)?.let { return it }
val typeQualifierAnnotation =
annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor)
@@ -75,18 +80,23 @@ class SignatureEnhancement(
val jsr305State = annotationTypeQualifierResolver.resolveJsr305AnnotationState(annotationDescriptor)
if (jsr305State.isIgnore) return null
return extractNullabilityFromKnownAnnotations(typeQualifierAnnotation)?.copy(isForWarningOnly = jsr305State.isWarning)
return extractNullabilityFromKnownAnnotations(typeQualifierAnnotation, areImprovementsEnabled, typeParameterBounds)
?.copy(isForWarningOnly = jsr305State.isWarning)
}
private fun extractNullabilityFromKnownAnnotations(
annotationDescriptor: AnnotationDescriptor
annotationDescriptor: AnnotationDescriptor,
areImprovementsEnabled: Boolean,
typeParameterBounds: Boolean
): NullabilityQualifierWithMigrationStatus? {
val annotationFqName = annotationDescriptor.fqName ?: return null
val isForWarningOnly = annotationDescriptor is LazyJavaAnnotationDescriptor
&& (annotationDescriptor.isFreshlySupportedTypeUseAnnotation || typeParameterBounds)
&& !areImprovementsEnabled
val migrationStatus =
jspecifyMigrationStatus(annotationFqName)
?: commonMigrationStatus(annotationFqName, annotationDescriptor)
?: return null
val migrationStatus = jspecifyMigrationStatus(annotationFqName)
?: commonMigrationStatus(annotationFqName, annotationDescriptor, isForWarningOnly)
?: return null
return if (!migrationStatus.isForWarningOnly
&& annotationDescriptor is PossiblyExternalAnnotationDescriptor
@@ -111,17 +121,18 @@ class SignatureEnhancement(
private fun commonMigrationStatus(
annotationFqName: FqName,
annotationDescriptor: AnnotationDescriptor
annotationDescriptor: AnnotationDescriptor,
isForWarningOnly: Boolean = false
): NullabilityQualifierWithMigrationStatus? = when {
annotationFqName in NULLABLE_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
annotationFqName in NOT_NULL_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
annotationFqName == JAVAX_NONNULL_ANNOTATION -> annotationDescriptor.extractNullabilityTypeFromArgument()
annotationFqName in NULLABLE_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
annotationFqName in NOT_NULL_ANNOTATIONS -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
annotationFqName == JAVAX_NONNULL_ANNOTATION -> annotationDescriptor.extractNullabilityTypeFromArgument(isForWarningOnly)
annotationFqName == COMPATQUAL_NULLABLE_ANNOTATION && javaTypeEnhancementState.enableCompatqualCheckerFrameworkAnnotations ->
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE)
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NULLABLE, isForWarningOnly)
annotationFqName == COMPATQUAL_NONNULL_ANNOTATION && javaTypeEnhancementState.enableCompatqualCheckerFrameworkAnnotations ->
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL, isForWarningOnly)
annotationFqName == ANDROIDX_RECENTLY_NON_NULL_ANNOTATION -> NullabilityQualifierWithMigrationStatus(
NullabilityQualifier.NOT_NULL,
@@ -326,10 +337,10 @@ class SignatureEnhancement(
typeParameterForArgument: TypeParameterDescriptor?,
isFromStarProjection: Boolean
): JavaTypeQualifiers {
val areImprovementsEnabled = containerContext.components.settings.typeEnhancementImprovements
val composedAnnotation =
if (isHeadTypeConstructor && typeContainer is TypeParameterDescriptor) {
composeAnnotations(typeContainer.annotations, annotations)
} else if (isHeadTypeConstructor && typeContainer != null) {
if (isHeadTypeConstructor && typeContainer != null && typeContainer !is TypeParameterDescriptor && areImprovementsEnabled) {
val filteredContainerAnnotations = typeContainer.annotations.filter {
val (_, targets) = annotationTypeQualifierResolver.resolveAnnotation(it) ?: return@filter false
/*
@@ -343,6 +354,8 @@ class SignatureEnhancement(
AnnotationQualifierApplicabilityType.TYPE_USE !in targets
}
composeAnnotations(Annotations.create(filteredContainerAnnotations), annotations)
} else if (isHeadTypeConstructor && typeContainer != null) {
composeAnnotations(typeContainer.annotations, annotations)
} else annotations
fun <T : Any> List<FqName>.ifPresent(qualifier: T) =
@@ -361,7 +374,8 @@ class SignatureEnhancement(
val (nullabilityFromBoundsForTypeBasedOnTypeParameter, isTypeParameterWithNotNullableBounds) =
nullabilityInfoBoundsForTypeParameterUsage()
val annotationsNullability = composedAnnotation.extractNullability()?.takeUnless { isFromStarProjection }
val annotationsNullability = composedAnnotation.extractNullability(areImprovementsEnabled, typeParameterBounds)
?.takeUnless { isFromStarProjection }
val nullabilityInfo =
annotationsNullability
?: computeNullabilityInfoInTheAbsenceOfExplicitAnnotation(
@@ -452,8 +466,11 @@ class SignatureEnhancement(
}
}
private fun Annotations.extractNullability(): NullabilityQualifierWithMigrationStatus? =
this.firstNotNullResult { extractNullability(it) }
private fun Annotations.extractNullability(
areImprovementsEnabled: Boolean,
typeParameterBounds: Boolean
): NullabilityQualifierWithMigrationStatus? =
this.firstNotNullResult { extractNullability(it, areImprovementsEnabled, typeParameterBounds) }
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {