Minor. Reformat signatureEnhancement.kt

This commit is contained in:
Denis Zharkov
2018-02-06 15:31:02 +03:00
parent 8edf8b9e4d
commit cfd612e2c1
@@ -40,8 +40,8 @@ import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import org.jetbrains.kotlin.utils.addToStdlib.safeAs import org.jetbrains.kotlin.utils.addToStdlib.safeAs
data class NullabilityQualifierWithMigrationStatus( data class NullabilityQualifierWithMigrationStatus(
val qualifier: NullabilityQualifier, val qualifier: NullabilityQualifier,
val isForWarningOnly: Boolean = false val isForWarningOnly: Boolean = false
) )
class SignatureEnhancement( class SignatureEnhancement(
@@ -51,8 +51,8 @@ class SignatureEnhancement(
private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? { private fun AnnotationDescriptor.extractNullabilityTypeFromArgument(): NullabilityQualifierWithMigrationStatus? {
val enumValue = firstArgument() as? EnumValue val enumValue = firstArgument() as? EnumValue
// if no argument is specified, use default value: NOT_NULL // if no argument is specified, use default value: NOT_NULL
?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) ?: return NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
return when (enumValue.enumEntryName.asString()) { return when (enumValue.enumEntryName.asString()) {
"ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL) "ALWAYS" -> NullabilityQualifierWithMigrationStatus(NullabilityQualifier.NOT_NULL)
@@ -66,8 +66,8 @@ class SignatureEnhancement(
extractNullabilityFromKnownAnnotations(annotationDescriptor)?.let { return it } extractNullabilityFromKnownAnnotations(annotationDescriptor)?.let { return it }
val typeQualifierAnnotation = val typeQualifierAnnotation =
annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor) annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor)
?: return null ?: return null
val jsr305State = annotationTypeQualifierResolver.resolveJsr305AnnotationState(annotationDescriptor) val jsr305State = annotationTypeQualifierResolver.resolveJsr305AnnotationState(annotationDescriptor)
if (jsr305State.isIgnore) return null if (jsr305State.isIgnore) return null
@@ -76,7 +76,7 @@ class SignatureEnhancement(
} }
private fun extractNullabilityFromKnownAnnotations( private fun extractNullabilityFromKnownAnnotations(
annotationDescriptor: AnnotationDescriptor annotationDescriptor: AnnotationDescriptor
): NullabilityQualifierWithMigrationStatus? { ): NullabilityQualifierWithMigrationStatus? {
val annotationFqName = annotationDescriptor.fqName ?: return null val annotationFqName = annotationDescriptor.fqName ?: return null
@@ -114,26 +114,26 @@ class SignatureEnhancement(
// When loading method as an override for a property, all annotations are stick to its getter // When loading method as an override for a property, all annotations are stick to its getter
val annotationOwnerForMember = val annotationOwnerForMember =
if (this is JavaPropertyDescriptor && getter?.isDefault == false) if (this is JavaPropertyDescriptor && getter?.isDefault == false)
getter!! getter!!
else else
this this
val receiverTypeEnhancement = val receiverTypeEnhancement =
if (extensionReceiverParameter != null) if (extensionReceiverParameter != null)
partsForValueParameter( partsForValueParameter(
parameterDescriptor = parameterDescriptor =
annotationOwnerForMember.safeAs<FunctionDescriptor>() annotationOwnerForMember.safeAs<FunctionDescriptor>()
?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER), ?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER),
methodContext = memberContext methodContext = memberContext
) { it.extensionReceiverParameter!!.type }.enhance() ) { it.extensionReceiverParameter!!.type }.enhance()
else null else null
val predefinedEnhancementInfo = val predefinedEnhancementInfo =
(this as? JavaMethodDescriptor) (this as? JavaMethodDescriptor)
?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) } ?.run { SignatureBuildingComponents.signature(this.containingDeclaration as ClassDescriptor, this.computeJvmDescriptor()) }
?.let { signature -> PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE[signature] } ?.let { signature -> PREDEFINED_FUNCTION_ENHANCEMENT_INFO_BY_SIGNATURE[signature] }
predefinedEnhancementInfo?.let { predefinedEnhancementInfo?.let {
@@ -142,10 +142,9 @@ class SignatureEnhancement(
} }
} }
val valueParameterEnhancements = annotationOwnerForMember.valueParameters.map { val valueParameterEnhancements = annotationOwnerForMember.valueParameters.map { p ->
p -> val enhancementResult = partsForValueParameter(p, memberContext) { it.valueParameters[p.index].type }
val enhancementResult =partsForValueParameter(p, memberContext) { it.valueParameters[p.index].type } .enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
val actualType = if (enhancementResult.wereChanges) enhancementResult.type else p.type val actualType = if (enhancementResult.wereChanges) enhancementResult.type else p.type
val hasDefaultValue = p.hasDefaultValueInAnnotation(actualType) val hasDefaultValue = p.hasDefaultValueInAnnotation(actualType)
@@ -155,21 +154,24 @@ class SignatureEnhancement(
} }
val returnTypeEnhancement = val returnTypeEnhancement =
parts( parts(
typeContainer = annotationOwnerForMember, isCovariant = true, typeContainer = annotationOwnerForMember, isCovariant = true,
containerContext = memberContext, containerContext = memberContext,
containerApplicabilityType = containerApplicabilityType =
if (this.safeAs<PropertyDescriptor>()?.isJavaField == true) if (this.safeAs<PropertyDescriptor>()?.isJavaField == true)
AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
else else
AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo) ) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
if ((receiverTypeEnhancement?.wereChanges == true) if ((receiverTypeEnhancement?.wereChanges == true)
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) { || returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }
) {
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
return this.enhance(receiverTypeEnhancement?.type, return this.enhance(receiverTypeEnhancement?.type,
valueParameterEnhancements.map { ValueParameterData(it.type, it.hasDefaultValue) }, returnTypeEnhancement.type) as D valueParameterEnhancements.map { ValueParameterData(it.type, it.hasDefaultValue) },
returnTypeEnhancement.type
) as D
} }
return this return this
@@ -179,19 +181,19 @@ class SignatureEnhancement(
val defaultValue = getDefaultValueFromAnnotation() val defaultValue = getDefaultValueFromAnnotation()
return when (defaultValue) { return when (defaultValue) {
is StringDefaultValue -> type.lexicalCastFrom(defaultValue.value) != null is StringDefaultValue -> type.lexicalCastFrom(defaultValue.value) != null
NullDefaultValue -> TypeUtils.acceptsNullable(type) NullDefaultValue -> TypeUtils.acceptsNullable(type)
null -> declaresDefaultValue() null -> declaresDefaultValue()
} && overriddenDescriptors.isEmpty() } && overriddenDescriptors.isEmpty()
} }
private inner class SignatureParts( private inner class SignatureParts(
private val typeContainer: Annotated?, private val typeContainer: Annotated?,
private val fromOverride: KotlinType, private val fromOverride: KotlinType,
private val fromOverridden: Collection<KotlinType>, private val fromOverridden: Collection<KotlinType>,
private val isCovariant: Boolean, private val isCovariant: Boolean,
private val containerContext: LazyJavaResolverContext, private val containerContext: LazyJavaResolverContext,
private val containerApplicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType private val containerApplicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType
) { ) {
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult { fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
val qualifiers = computeIndexedQualifiersForOverride() val qualifiers = computeIndexedQualifiersForOverride()
@@ -215,66 +217,67 @@ class SignatureEnhancement(
val mapping = JavaToKotlinClassMap val mapping = JavaToKotlinClassMap
return JavaTypeQualifiers( return JavaTypeQualifiers(
when { when {
lower.isMarkedNullable -> NullabilityQualifier.NULLABLE lower.isMarkedNullable -> NullabilityQualifier.NULLABLE
!upper.isMarkedNullable -> NullabilityQualifier.NOT_NULL !upper.isMarkedNullable -> NullabilityQualifier.NOT_NULL
else -> null else -> null
}, },
when { when {
mapping.isReadOnly(lower) -> MutabilityQualifier.READ_ONLY mapping.isReadOnly(lower) -> MutabilityQualifier.READ_ONLY
mapping.isMutable(upper) -> MutabilityQualifier.MUTABLE mapping.isMutable(upper) -> MutabilityQualifier.MUTABLE
else -> null else -> null
}, },
isNotNullTypeParameter = unwrap() is NotNullTypeParameter) isNotNullTypeParameter = unwrap() is NotNullTypeParameter
)
} }
private fun KotlinType.extractQualifiersFromAnnotations( private fun KotlinType.extractQualifiersFromAnnotations(
isHeadTypeConstructor: Boolean, isHeadTypeConstructor: Boolean,
defaultQualifiersForType: JavaTypeQualifiers? defaultQualifiersForType: JavaTypeQualifiers?
): JavaTypeQualifiers { ): JavaTypeQualifiers {
val composedAnnotation = val composedAnnotation =
if (isHeadTypeConstructor && typeContainer != null) if (isHeadTypeConstructor && typeContainer != null)
composeAnnotations(typeContainer.annotations, annotations) composeAnnotations(typeContainer.annotations, annotations)
else else
annotations annotations
fun <T : Any> List<FqName>.ifPresent(qualifier: T) = fun <T : Any> List<FqName>.ifPresent(qualifier: T) =
if (any { composedAnnotation.findAnnotation(it) != null }) qualifier else null if (any { composedAnnotation.findAnnotation(it) != null }) qualifier else null
fun <T : Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null fun <T : Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
val defaultTypeQualifier = val defaultTypeQualifier =
if (isHeadTypeConstructor) if (isHeadTypeConstructor)
containerContext.defaultTypeQualifiers?.get(containerApplicabilityType) containerContext.defaultTypeQualifiers?.get(containerApplicabilityType)
else else
defaultQualifiersForType defaultQualifiersForType
val nullabilityInfo = val nullabilityInfo =
composedAnnotation.extractNullability() composedAnnotation.extractNullability()
?: defaultTypeQualifier?.nullability?.let { ?: defaultTypeQualifier?.nullability?.let {
NullabilityQualifierWithMigrationStatus( NullabilityQualifierWithMigrationStatus(
defaultTypeQualifier.nullability, defaultTypeQualifier.nullability,
defaultTypeQualifier.isNullabilityQualifierForWarning defaultTypeQualifier.isNullabilityQualifierForWarning
) )
} }
return JavaTypeQualifiers( return JavaTypeQualifiers(
nullabilityInfo?.qualifier, nullabilityInfo?.qualifier,
uniqueNotNull( uniqueNotNull(
READ_ONLY_ANNOTATIONS.ifPresent( READ_ONLY_ANNOTATIONS.ifPresent(
MutabilityQualifier.READ_ONLY MutabilityQualifier.READ_ONLY
),
MUTABLE_ANNOTATIONS.ifPresent(
MutabilityQualifier.MUTABLE
)
), ),
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL && isTypeParameter(), MUTABLE_ANNOTATIONS.ifPresent(
isNullabilityQualifierForWarning = nullabilityInfo?.isForWarningOnly == true MutabilityQualifier.MUTABLE
)
),
isNotNullTypeParameter = nullabilityInfo?.qualifier == NullabilityQualifier.NOT_NULL && isTypeParameter(),
isNullabilityQualifierForWarning = nullabilityInfo?.isForWarningOnly == true
) )
} }
private fun Annotations.extractNullability(): NullabilityQualifierWithMigrationStatus? = private fun Annotations.extractNullability(): NullabilityQualifierWithMigrationStatus? =
this.firstNotNullResult(this@SignatureEnhancement::extractNullability) this.firstNotNullResult(this@SignatureEnhancement::extractNullability)
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers { private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {
@@ -311,19 +314,18 @@ class SignatureEnhancement(
val c = ownerContext.copyWithNewDefaultTypeQualifiers(type.annotations) val c = ownerContext.copyWithNewDefaultTypeQualifiers(type.annotations)
list.add( list.add(
TypeAndDefaultQualifiers( TypeAndDefaultQualifiers(
type, type,
c.defaultTypeQualifiers c.defaultTypeQualifiers
?.get(AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_USE) ?.get(AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_USE)
) )
) )
for (arg in type.arguments) { for (arg in type.arguments) {
if (arg.isStarProjection) { if (arg.isStarProjection) {
// TODO: sort out how to handle wildcards // TODO: sort out how to handle wildcards
list.add(TypeAndDefaultQualifiers(arg.type, null)) list.add(TypeAndDefaultQualifiers(arg.type, null))
} } else {
else {
add(arg.type, c) add(arg.type, c)
} }
} }
@@ -334,16 +336,16 @@ class SignatureEnhancement(
} }
private fun KotlinType.computeQualifiersForOverride( private fun KotlinType.computeQualifiersForOverride(
fromSupertypes: Collection<KotlinType>, fromSupertypes: Collection<KotlinType>,
defaultQualifiersForType: JavaTypeQualifiers?, defaultQualifiersForType: JavaTypeQualifiers?,
isHeadTypeConstructor: Boolean isHeadTypeConstructor: Boolean
): JavaTypeQualifiers { ): JavaTypeQualifiers {
val superQualifiers = fromSupertypes.map { it.extractQualifiers() } val superQualifiers = fromSupertypes.map { it.extractQualifiers() }
val mutabilityFromSupertypes = superQualifiers.mapNotNull { it.mutability }.toSet() val mutabilityFromSupertypes = superQualifiers.mapNotNull { it.mutability }.toSet()
val nullabilityFromSupertypes = superQualifiers.mapNotNull { it.nullability }.toSet() val nullabilityFromSupertypes = superQualifiers.mapNotNull { it.nullability }.toSet()
val nullabilityFromSupertypesWithWarning = fromSupertypes val nullabilityFromSupertypesWithWarning = fromSupertypes
.mapNotNull { it.unwrapEnhancement().extractQualifiers().nullability } .mapNotNull { it.unwrapEnhancement().extractQualifiers().nullability }
.toSet() .toSet()
val own = extractQualifiersFromAnnotations(isHeadTypeConstructor, defaultQualifiersForType) val own = extractQualifiersFromAnnotations(isHeadTypeConstructor, defaultQualifiersForType)
val ownNullability = own.takeIf { !it.isNullabilityQualifierForWarning }?.nullability val ownNullability = own.takeIf { !it.isNullabilityQualifierForWarning }?.nullability
@@ -352,25 +354,25 @@ class SignatureEnhancement(
val isCovariantPosition = isCovariant && isHeadTypeConstructor val isCovariantPosition = isCovariant && isHeadTypeConstructor
val nullability = nullabilityFromSupertypes.select(ownNullability, isCovariantPosition) val nullability = nullabilityFromSupertypes.select(ownNullability, isCovariantPosition)
val mutability = val mutability =
mutabilityFromSupertypes mutabilityFromSupertypes
.select(MutabilityQualifier.MUTABLE, MutabilityQualifier.READ_ONLY, own.mutability, isCovariantPosition) .select(MutabilityQualifier.MUTABLE, MutabilityQualifier.READ_ONLY, own.mutability, isCovariantPosition)
val canChange = ownNullabilityForWarning != ownNullability || nullabilityFromSupertypesWithWarning != nullabilityFromSupertypes val canChange = ownNullabilityForWarning != ownNullability || nullabilityFromSupertypesWithWarning != nullabilityFromSupertypes
val isAnyNonNullTypeParameter = own.isNotNullTypeParameter || superQualifiers.any { it.isNotNullTypeParameter } val isAnyNonNullTypeParameter = own.isNotNullTypeParameter || superQualifiers.any { it.isNotNullTypeParameter }
if (nullability == null && canChange) { if (nullability == null && canChange) {
val nullabilityWithWarning = val nullabilityWithWarning =
nullabilityFromSupertypesWithWarning.select(ownNullabilityForWarning, isCovariantPosition) nullabilityFromSupertypesWithWarning.select(ownNullabilityForWarning, isCovariantPosition)
return createJavaTypeQualifiers( return createJavaTypeQualifiers(
nullabilityWithWarning, mutability, nullabilityWithWarning, mutability,
forWarning = true, isAnyNonNullTypeParameter = isAnyNonNullTypeParameter forWarning = true, isAnyNonNullTypeParameter = isAnyNonNullTypeParameter
) )
} }
return createJavaTypeQualifiers( return createJavaTypeQualifiers(
nullability, mutability, nullability, mutability,
forWarning = nullability == null, forWarning = nullability == null,
isAnyNonNullTypeParameter = isAnyNonNullTypeParameter isAnyNonNullTypeParameter = isAnyNonNullTypeParameter
) )
} }
@@ -378,49 +380,49 @@ class SignatureEnhancement(
private open class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean) private open class PartEnhancementResult(val type: KotlinType, val wereChanges: Boolean)
private class ValueParameterEnhancementResult( private class ValueParameterEnhancementResult(
type: KotlinType, type: KotlinType,
val hasDefaultValue: Boolean, val hasDefaultValue: Boolean,
wereChanges: Boolean wereChanges: Boolean
) : PartEnhancementResult(type, wereChanges) ) : PartEnhancementResult(type, wereChanges)
private fun CallableMemberDescriptor.partsForValueParameter( private fun CallableMemberDescriptor.partsForValueParameter(
// TODO: investigate if it's really can be a null (check properties' with extension overrides in Java) // TODO: investigate if it's really can be a null (check properties' with extension overrides in Java)
parameterDescriptor: ValueParameterDescriptor?, parameterDescriptor: ValueParameterDescriptor?,
methodContext: LazyJavaResolverContext, methodContext: LazyJavaResolverContext,
collector: (CallableMemberDescriptor) -> KotlinType collector: (CallableMemberDescriptor) -> KotlinType
) = parts( ) = parts(
parameterDescriptor, false, parameterDescriptor, false,
parameterDescriptor?.let { methodContext.copyWithNewDefaultTypeQualifiers(it.annotations) } ?: methodContext, parameterDescriptor?.let { methodContext.copyWithNewDefaultTypeQualifiers(it.annotations) } ?: methodContext,
AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER, AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER,
collector collector
) )
private fun CallableMemberDescriptor.parts( private fun CallableMemberDescriptor.parts(
typeContainer: Annotated?, typeContainer: Annotated?,
isCovariant: Boolean, isCovariant: Boolean,
containerContext: LazyJavaResolverContext, containerContext: LazyJavaResolverContext,
containerApplicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType, containerApplicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType,
collector: (CallableMemberDescriptor) -> KotlinType collector: (CallableMemberDescriptor) -> KotlinType
): SignatureParts { ): SignatureParts {
return SignatureParts( return SignatureParts(
typeContainer, typeContainer,
collector(this), collector(this),
this.overriddenDescriptors.map { this.overriddenDescriptors.map {
collector(it) collector(it)
}, },
isCovariant, isCovariant,
// recompute default type qualifiers using type annotations // recompute default type qualifiers using type annotations
containerContext.copyWithNewDefaultTypeQualifiers(collector(this).annotations), containerContext.copyWithNewDefaultTypeQualifiers(collector(this).annotations),
containerApplicabilityType containerApplicabilityType
) )
} }
} }
private fun createJavaTypeQualifiers( private fun createJavaTypeQualifiers(
nullability: NullabilityQualifier?, nullability: NullabilityQualifier?,
mutability: MutabilityQualifier?, mutability: MutabilityQualifier?,
forWarning: Boolean, forWarning: Boolean,
isAnyNonNullTypeParameter: Boolean isAnyNonNullTypeParameter: Boolean
): JavaTypeQualifiers { ): JavaTypeQualifiers {
if (!isAnyNonNullTypeParameter || nullability != NullabilityQualifier.NOT_NULL) { if (!isAnyNonNullTypeParameter || nullability != NullabilityQualifier.NOT_NULL) {
return JavaTypeQualifiers(nullability, mutability, false, forWarning) return JavaTypeQualifiers(nullability, mutability, false, forWarning)
@@ -443,12 +445,12 @@ private fun <T : Any> Set<T>.select(low: T, high: T, own: T?, isCovariant: Boole
} }
private fun Set<NullabilityQualifier>.select(own: NullabilityQualifier?, isCovariant: Boolean) = private fun Set<NullabilityQualifier>.select(own: NullabilityQualifier?, isCovariant: Boolean) =
if (own == NullabilityQualifier.FORCE_FLEXIBILITY) if (own == NullabilityQualifier.FORCE_FLEXIBILITY)
NullabilityQualifier.FORCE_FLEXIBILITY NullabilityQualifier.FORCE_FLEXIBILITY
else else
select(NullabilityQualifier.NOT_NULL, NullabilityQualifier.NULLABLE, own, isCovariant) select(NullabilityQualifier.NOT_NULL, NullabilityQualifier.NULLABLE, own, isCovariant)
private data class TypeAndDefaultQualifiers( private data class TypeAndDefaultQualifiers(
val type: KotlinType, val type: KotlinType,
val defaultQualifiers: JavaTypeQualifiers? val defaultQualifiers: JavaTypeQualifiers?
) )