Don't enhance previously erased value parameters for jspecify strict mode
^KT-48261 Fixed
This commit is contained in:
+9
-2
@@ -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 } }
|
||||
}
|
||||
|
||||
+5
-2
@@ -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 }),
|
||||
|
||||
+2
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
@@ -481,6 +481,7 @@ class LazyJavaClassMemberScope(
|
||||
)
|
||||
setSignatureChange()
|
||||
setPreserveSourceElement()
|
||||
putUserData(JavaMethodDescriptor.HAS_ERASED_VALUE_PARAMETERS, true)
|
||||
}.build()
|
||||
}
|
||||
}
|
||||
|
||||
+25
-12
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user