FE: don't lose annotations on Java primitive arrays

but only use them to enhance for warnings for now.

^KT-48861 Fixed
This commit is contained in:
pyos
2021-09-22 13:14:05 +02:00
committed by Mikhail Glukhikh
parent c6e4d034cb
commit 6c6d653e85
26 changed files with 245 additions and 126 deletions
@@ -30,7 +30,7 @@ abstract class AbstractSignatureParts<TAnnotation : Any> {
open val forceOnlyHeadTypeConstructor: Boolean
get() = false
abstract val TAnnotation.forceWarning: Boolean
abstract fun TAnnotation.forceWarning(unenhancedType: KotlinTypeMarker?): Boolean
abstract val KotlinTypeMarker.annotations: Iterable<TAnnotation>
abstract val KotlinTypeMarker.enhancedForWarnings: KotlinTypeMarker?
@@ -91,7 +91,7 @@ abstract class AbstractSignatureParts<TAnnotation : Any> {
}
val annotationsMutability = annotationTypeQualifierResolver.extractMutability(composedAnnotation)
val annotationsNullability = annotationTypeQualifierResolver.extractNullability(composedAnnotation) { forceWarning }
val annotationsNullability = annotationTypeQualifierResolver.extractNullability(composedAnnotation) { forceWarning(type) }
if (annotationsNullability != null) {
return JavaTypeQualifiers(
annotationsNullability.qualifier, annotationsMutability,
@@ -83,6 +83,7 @@ interface JavaResolverSettings {
val correctNullabilityForNotNullTypeParameter: Boolean
val typeEnhancementImprovementsInStrictMode: Boolean
val ignoreNullabilityForErasedValueParameters: Boolean
val enhancePrimitiveArrays: Boolean
object Default : JavaResolverSettings {
override val correctNullabilityForNotNullTypeParameter: Boolean
@@ -93,18 +94,23 @@ interface JavaResolverSettings {
override val ignoreNullabilityForErasedValueParameters: Boolean
get() = false
override val enhancePrimitiveArrays: Boolean
get() = false
}
companion object {
fun create(
correctNullabilityForNotNullTypeParameter: Boolean,
typeEnhancementImprovementsInStrictMode: Boolean,
ignoreNullabilityForErasedValueParameters: Boolean
ignoreNullabilityForErasedValueParameters: Boolean,
enhancePrimitiveArrays: Boolean,
): JavaResolverSettings =
object : JavaResolverSettings {
override val correctNullabilityForNotNullTypeParameter get() = correctNullabilityForNotNullTypeParameter
override val typeEnhancementImprovementsInStrictMode get() = typeEnhancementImprovementsInStrictMode
override val ignoreNullabilityForErasedValueParameters get() = ignoreNullabilityForErasedValueParameters
override val enhancePrimitiveArrays get() = enhancePrimitiveArrays
}
}
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMapper
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.annotations.CompositeAnnotations
import org.jetbrains.kotlin.load.java.extractNullabilityAnnotationOnBoundedWildcard
import org.jetbrains.kotlin.types.TypeUsage.COMMON
import org.jetbrains.kotlin.types.TypeUsage.SUPERTYPE
@@ -69,13 +70,13 @@ class JavaTypeResolver(
val annotations = LazyJavaAnnotations(c, arrayType, areAnnotationsFreshlySupported = true)
if (primitiveType != null) {
val jetType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType)
jetType.replaceAnnotations(Annotations.create(annotations + jetType.annotations))
val kotlinType = c.module.builtIns.getPrimitiveArrayKotlinType(primitiveType).let {
it.replaceAnnotations(CompositeAnnotations(it.annotations, annotations)) as SimpleType
}
return if (attr.isForAnnotationParameter)
jetType
else KotlinTypeFactory.flexibleType(jetType, jetType.makeNullableAsSpecified(true))
kotlinType
else KotlinTypeFactory.flexibleType(kotlinType, kotlinType.makeNullableAsSpecified(true))
}
val componentType = transformJavaType(
@@ -249,11 +249,15 @@ private class SignatureParts(
override val typeSystem: TypeSystemInferenceExtensionContext
get() = SimpleClassicTypeSystemContext
override val AnnotationDescriptor.forceWarning: Boolean
get() = (this is PossiblyExternalAnnotationDescriptor && isIdeExternalAnnotation) ||
override fun AnnotationDescriptor.forceWarning(unenhancedType: KotlinTypeMarker?): Boolean =
(this is PossiblyExternalAnnotationDescriptor && isIdeExternalAnnotation) ||
(this is LazyJavaAnnotationDescriptor && !enableImprovementsInStrictMode &&
(isFreshlySupportedTypeUseAnnotation ||
containerApplicabilityType == AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS))
containerApplicabilityType == AnnotationQualifierApplicabilityType.TYPE_PARAMETER_BOUNDS)) ||
// Previously, type use annotations on primitive arrays were lost, so temporarily treat them as warnings.
(unenhancedType != null && KotlinBuiltIns.isPrimitiveArray(unenhancedType as KotlinType) &&
annotationTypeQualifierResolver.isTypeUseAnnotation(this) &&
!containerContext.components.settings.enhancePrimitiveArrays)
override val KotlinTypeMarker.annotations: Iterable<AnnotationDescriptor>
get() = (this as KotlinType).annotations