Don't enhance previously erased value parameters for jspecify strict mode

^KT-48261 Fixed
This commit is contained in:
Victor Petukhov
2021-10-06 14:15:25 +03:00
parent e77f72071d
commit d015d3bc0e
19 changed files with 348 additions and 21 deletions
@@ -161,7 +161,9 @@ abstract class AbstractSignatureParts<TAnnotation : Any> {
}
fun KotlinTypeMarker.computeIndexedQualifiers(
overrides: Iterable<KotlinTypeMarker>, predefined: TypeEnhancementInfo?
overrides: Iterable<KotlinTypeMarker>,
predefined: TypeEnhancementInfo?,
ignoreDeclarationNullabilityAnnotations: Boolean = false
): IndexedJavaTypeQualifiers {
val indexedThisType = toIndexed()
val indexedFromSupertypes = overrides.map { it.toIndexed() }
@@ -178,7 +180,12 @@ abstract class AbstractSignatureParts<TAnnotation : Any> {
val computedResult = Array(treeSize) { index ->
val qualifiers = indexedThisType[index].extractQualifiersFromAnnotations()
val superQualifiers = indexedFromSupertypes.mapNotNull { it.getOrNull(index)?.type?.extractQualifiers() }
qualifiers.computeQualifiersForOverride(superQualifiers, index == 0 && isCovariant, index == 0 && containerIsVarargParameter)
qualifiers.computeQualifiersForOverride(
superQualifiers,
index == 0 && isCovariant,
index == 0 && containerIsVarargParameter,
ignoreDeclarationNullabilityAnnotations
)
}
return { index -> predefined?.map?.get(index) ?: computedResult.getOrElse(index) { JavaTypeQualifiers.NONE } }
}
@@ -35,7 +35,8 @@ private val JavaTypeQualifiers.nullabilityForErrors: NullabilityQualifier?
fun JavaTypeQualifiers.computeQualifiersForOverride(
superQualifiers: Collection<JavaTypeQualifiers>,
isCovariant: Boolean,
isForVarargParameter: Boolean
isForVarargParameter: Boolean,
ignoreDeclarationNullabilityAnnotations: Boolean
): JavaTypeQualifiers {
val newNullabilityForErrors = superQualifiers.mapNotNull { it.nullabilityForErrors }.toSet()
.select(nullabilityForErrors, isCovariant)
@@ -45,7 +46,9 @@ fun JavaTypeQualifiers.computeQualifiersForOverride(
.select(MutabilityQualifier.MUTABLE, MutabilityQualifier.READ_ONLY, mutability, isCovariant)
// Vararg value parameters effectively have non-nullable type in Kotlin
// and having nullable types in Java may lead to impossibility of overriding them in Kotlin
val realNullability = newNullability?.takeUnless { isForVarargParameter && it == NullabilityQualifier.NULLABLE }
val realNullability = newNullability?.takeUnless {
ignoreDeclarationNullabilityAnnotations || (isForVarargParameter && it == NullabilityQualifier.NULLABLE)
}
return JavaTypeQualifiers(
realNullability, newMutability,
realNullability == NullabilityQualifier.NOT_NULL && (definitelyNotNull || superQualifiers.any { it.definitelyNotNull }),
@@ -37,6 +37,8 @@ public class JavaMethodDescriptor extends SimpleFunctionDescriptorImpl implement
public static final UserDataKey<ValueParameterDescriptor> ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER =
new UserDataKey<ValueParameterDescriptor>() {};
public static final UserDataKey<Boolean> HAS_ERASED_VALUE_PARAMETERS = new UserDataKey<Boolean>() {};
private enum ParameterNamesStatus {
NON_STABLE_DECLARED(false, false),
STABLE_DECLARED(true, false),
@@ -82,6 +82,7 @@ class JavaResolverComponents(
interface JavaResolverSettings {
val correctNullabilityForNotNullTypeParameter: Boolean
val typeEnhancementImprovementsInStrictMode: Boolean
val ignoreNullabilityForErasedValueParameters: Boolean
object Default : JavaResolverSettings {
override val correctNullabilityForNotNullTypeParameter: Boolean
@@ -89,16 +90,21 @@ interface JavaResolverSettings {
override val typeEnhancementImprovementsInStrictMode: Boolean
get() = false
override val ignoreNullabilityForErasedValueParameters: Boolean
get() = false
}
companion object {
fun create(
correctNullabilityForNotNullTypeParameter: Boolean,
typeEnhancementImprovementsInStrictMode: Boolean
typeEnhancementImprovementsInStrictMode: Boolean,
ignoreNullabilityForErasedValueParameters: Boolean
): JavaResolverSettings =
object : JavaResolverSettings {
override val correctNullabilityForNotNullTypeParameter get() = correctNullabilityForNotNullTypeParameter
override val typeEnhancementImprovementsInStrictMode get() = typeEnhancementImprovementsInStrictMode
override val ignoreNullabilityForErasedValueParameters get() = ignoreNullabilityForErasedValueParameters
}
}
}
@@ -481,6 +481,7 @@ class LazyJavaClassMemberScope(
)
setSignatureChange()
setPreserveSourceElement()
putUserData(JavaMethodDescriptor.HAS_ERASED_VALUE_PARAMETERS, true)
}.build()
}
}
@@ -22,14 +22,12 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.load.java.AnnotationQualifierApplicabilityType
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
import org.jetbrains.kotlin.load.java.DeprecationCausedByFunctionNInfo
import org.jetbrains.kotlin.load.java.JavaTypeQualifiersByElementType
import org.jetbrains.kotlin.load.java.*
import org.jetbrains.kotlin.load.java.descriptors.JavaCallableMemberDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.descriptors.PossiblyExternalAnnotationDescriptor
import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents
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
@@ -94,10 +92,11 @@ class SignatureEnhancement(private val typeEnhancement: JavaTypeEnhancement) {
val receiverTypeEnhancement =
if (extensionReceiverParameter != null)
enhanceValueParameter(
parameterDescriptor =
annotationOwnerForMember.safeAs<FunctionDescriptor>()
parameterDescriptor = annotationOwnerForMember.safeAs<FunctionDescriptor>()
?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER),
methodContext = memberContext, predefined = null
methodContext = memberContext,
predefined = null,
ignoreDeclarationNullabilityAnnotations = false
) { it.extensionReceiverParameter!!.type }
else null
@@ -113,9 +112,15 @@ class SignatureEnhancement(private val typeEnhancement: JavaTypeEnhancement) {
}
}
val ignoreDeclarationNullabilityAnnotations =
(isJspecifyEnabledInStrictMode(c.components.javaTypeEnhancementState)
|| memberContext.components.settings.ignoreNullabilityForErasedValueParameters)
&& hasErasedValueParameters(this)
val valueParameterEnhancements = annotationOwnerForMember.valueParameters.map { p ->
val predefined = predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index)
enhanceValueParameter(p, memberContext, predefined) { it.valueParameters[p.index].type }
enhanceValueParameter(p, memberContext, predefined, ignoreDeclarationNullabilityAnnotations) {
it.valueParameters[p.index].type
}
}
val returnTypeEnhancement =
@@ -189,12 +194,13 @@ class SignatureEnhancement(private val typeEnhancement: JavaTypeEnhancement) {
parameterDescriptor: ValueParameterDescriptor?,
methodContext: LazyJavaResolverContext,
predefined: TypeEnhancementInfo?,
ignoreDeclarationNullabilityAnnotations: Boolean,
collector: (CallableMemberDescriptor) -> KotlinType
) = enhance(
parameterDescriptor, false,
parameterDescriptor?.let { methodContext.copyWithNewDefaultTypeQualifiers(it.annotations) } ?: methodContext,
AnnotationQualifierApplicabilityType.VALUE_PARAMETER,
predefined, collector
predefined, ignoreDeclarationNullabilityAnnotations, collector
)
private fun CallableMemberDescriptor.enhance(
@@ -203,14 +209,21 @@ class SignatureEnhancement(private val typeEnhancement: JavaTypeEnhancement) {
containerContext: LazyJavaResolverContext,
containerApplicabilityType: AnnotationQualifierApplicabilityType,
predefined: TypeEnhancementInfo?,
ignoreDeclarationNullabilityAnnotations: Boolean = false,
collector: (CallableMemberDescriptor) -> KotlinType
): KotlinType? {
return SignatureParts(typeContainer, isCovariant, containerContext, containerApplicabilityType)
.enhance(collector(this), overriddenDescriptors.map { collector(it) }, predefined)
.enhance(collector(this), overriddenDescriptors.map { collector(it) }, predefined, ignoreDeclarationNullabilityAnnotations)
}
private fun SignatureParts.enhance(type: KotlinType, overrides: List<KotlinType>, predefined: TypeEnhancementInfo? = null) =
with(typeEnhancement) { type.enhance(type.computeIndexedQualifiers(overrides, predefined), skipRawTypeArguments) }
private fun SignatureParts.enhance(
type: KotlinType,
overrides: List<KotlinType>,
predefined: TypeEnhancementInfo? = null,
ignoreDeclarationNullabilityAnnotations: Boolean = false
) = with(typeEnhancement) {
type.enhance(type.computeIndexedQualifiers(overrides, predefined, ignoreDeclarationNullabilityAnnotations), skipRawTypeArguments)
}
}
private class SignatureParts(
@@ -17,9 +17,8 @@
package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.builtins.jvm.JavaToKotlinClassMap
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.resolve.deprecation.DescriptorBasedDeprecationInfo
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
@@ -31,3 +30,9 @@ class DeprecationCausedByFunctionNInfo(override val target: DeclarationDescripto
}
internal fun Visibility.toDescriptorVisibility(): DescriptorVisibility = JavaDescriptorVisibilities.toDescriptorVisibility(this)
fun isJspecifyEnabledInStrictMode(javaTypeEnhancementState: JavaTypeEnhancementState) =
javaTypeEnhancementState.getReportLevelForAnnotation(JSPECIFY_ANNOTATIONS_PACKAGE) == ReportLevel.STRICT
fun hasErasedValueParameters(memberDescriptor: CallableMemberDescriptor) =
memberDescriptor is FunctionDescriptor && memberDescriptor.getUserData(JavaMethodDescriptor.HAS_ERASED_VALUE_PARAMETERS) == true