Support TypeQualifierDefault from JSR 305 for nullability qualifiers

#KT-10942 Fixed
This commit is contained in:
Denis Zharkov
2017-06-24 17:07:13 +03:00
parent 5141a88a53
commit e26c210d69
39 changed files with 1538 additions and 76 deletions
@@ -20,12 +20,16 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
private val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQualifierNickname")
private val TYPE_QUALIFIER_FQNAME = FqName("javax.annotation.meta.TypeQualifier")
private val TYPE_QUALIFIER_DEFAULT_FQNAME = FqName("javax.annotation.meta.TypeQualifierDefault")
class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
private val resolvedNicknames =
@@ -49,6 +53,58 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
return resolveTypeQualifierNickname(annotationClass)
}
enum class QualifierApplicabilityType {
METHOD_RETURN_TYPE, VALUE_PARAMETER, FIELD, TYPE_USE
}
class TypeQualifierWithApplicability(
private val typeQualifier: AnnotationDescriptor,
private val applicability: Int
) {
private fun isApplicableTo(elementType: QualifierApplicabilityType) = (applicability and (1 shl elementType.ordinal)) != 0
operator fun component1() = typeQualifier
operator fun component2() = QualifierApplicabilityType.values().filter(this::isApplicableTo)
}
fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? {
val typeQualifierDefaultAnnotatedClass =
annotationDescriptor.annotationClass?.takeIf { it.annotations.hasAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME) }
?: return null
val elementTypesMask =
annotationDescriptor.annotationClass!!
.annotations.findAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME)!!
.allValueArguments
.flatMap { (parameter, argument) ->
if (parameter.name == JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME)
argument.mapConstantToQualifierApplicabilityTypes()
else
emptyList()
}
.fold(0) { acc: Int, applicabilityType -> acc or (1 shl applicabilityType.ordinal) }
val typeQualifier =
typeQualifierDefaultAnnotatedClass.annotations.firstNotNullResult(this::resolveTypeQualifierAnnotation)
?: return null
return TypeQualifierWithApplicability(typeQualifier, elementTypesMask)
}
private fun ConstantValue<*>.mapConstantToQualifierApplicabilityTypes(): List<QualifierApplicabilityType> =
when (this) {
is ArrayValue -> value.flatMap { it.mapConstantToQualifierApplicabilityTypes() }
is EnumValue -> listOfNotNull(
when (value.name.identifier) {
"METHOD" -> QualifierApplicabilityType.METHOD_RETURN_TYPE
"FIELD" -> QualifierApplicabilityType.FIELD
"PARAMETER" -> QualifierApplicabilityType.VALUE_PARAMETER
"TYPE_USE" -> QualifierApplicabilityType.TYPE_USE
else -> null
}
)
else -> emptyList()
}
}
private val ClassDescriptor.isAnnotatedWithTypeQualifier: Boolean
@@ -26,7 +26,7 @@ class LazyJavaPackageFragmentProvider(
components: JavaResolverComponents
) : PackageFragmentProvider {
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY)
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null }
private val packageFragments: MemoizedFunctionToNullable<FqName, LazyJavaPackageFragment> =
c.storageManager.createMemoizedFunctionWithNullableValues {
@@ -17,10 +17,8 @@
package org.jetbrains.kotlin.load.java.lazy
import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
import org.jetbrains.kotlin.load.java.JavaClassFinder
@@ -28,11 +26,14 @@ import org.jetbrains.kotlin.load.java.components.*
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.JavaTypeQualifiers
import org.jetbrains.kotlin.load.java.typeEnhancement.NullabilityQualifier
import org.jetbrains.kotlin.load.java.typeEnhancement.SignatureEnhancement
import org.jetbrains.kotlin.load.kotlin.DeserializedDescriptorResolver
import org.jetbrains.kotlin.load.kotlin.KotlinClassFinder
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.storage.StorageManager
import java.util.*
class JavaResolverComponents(
val storageManager: StorageManager,
@@ -66,10 +67,33 @@ class JavaResolverComponents(
)
}
class LazyJavaResolverContext(
val components: JavaResolverComponents,
val typeParameterResolver: TypeParameterResolver
private typealias QualifierByApplicabilityType = EnumMap<AnnotationTypeQualifierResolver.QualifierApplicabilityType, NullabilityQualifier?>
class JavaTypeQualifiersByElementType(
internal val nullabilityQualifiers: QualifierByApplicabilityType
) {
operator fun get(
applicabilityType: AnnotationTypeQualifierResolver.QualifierApplicabilityType
): JavaTypeQualifiers? =
(
nullabilityQualifiers[applicabilityType]
?: nullabilityQualifiers[AnnotationTypeQualifierResolver.QualifierApplicabilityType.TYPE_USE]
)?.let { JavaTypeQualifiers(it, null, isNotNullTypeParameter = false) }
}
class LazyJavaResolverContext internal constructor(
val components: JavaResolverComponents,
val typeParameterResolver: TypeParameterResolver,
internal val delegateForDefaultTypeQualifiers: Lazy<JavaTypeQualifiersByElementType?>
) {
constructor(
components: JavaResolverComponents,
typeParameterResolver: TypeParameterResolver,
typeQualifiersComputation: () -> JavaTypeQualifiersByElementType?
) : this(components, typeParameterResolver, lazy(LazyThreadSafetyMode.NONE, typeQualifiersComputation))
val defaultTypeQualifiers: JavaTypeQualifiersByElementType? by delegateForDefaultTypeQualifiers
val typeResolver = JavaTypeResolver(this, typeParameterResolver)
val storageManager: StorageManager
@@ -80,14 +104,59 @@ class LazyJavaResolverContext(
fun LazyJavaResolverContext.child(
typeParameterResolver: TypeParameterResolver
) = LazyJavaResolverContext(components, typeParameterResolver)
) = LazyJavaResolverContext(components, typeParameterResolver, delegateForDefaultTypeQualifiers)
fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers(
additionalAnnotations: Annotations
): JavaTypeQualifiersByElementType? {
val typeQualifierDefaults =
additionalAnnotations.mapNotNull(components.annotationTypeQualifierResolver::resolveTypeQualifierDefaultAnnotation)
if (typeQualifierDefaults.isEmpty()) return defaultTypeQualifiers
val nullabilityQualifiers =
defaultTypeQualifiers?.nullabilityQualifiers?.let(::QualifierByApplicabilityType)
?: QualifierByApplicabilityType(AnnotationTypeQualifierResolver.QualifierApplicabilityType::class.java)
var wasUpdate = false
for ((typeQualifier, applicableTo) in typeQualifierDefaults) {
val nullability = components.signatureEnhancement.extractNullability(typeQualifier) ?: continue
for (applicabilityType in applicableTo) {
nullabilityQualifiers[applicabilityType] = nullability
wasUpdate = true
}
}
return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(nullabilityQualifiers)
}
fun LazyJavaResolverContext.replaceComponents(
components: JavaResolverComponents
) = LazyJavaResolverContext(components, typeParameterResolver)
) = LazyJavaResolverContext(components, typeParameterResolver, delegateForDefaultTypeQualifiers)
fun LazyJavaResolverContext.child(
private fun LazyJavaResolverContext.child(
containingDeclaration: DeclarationDescriptor,
typeParameterOwner: JavaTypeParameterListOwner?,
typeParametersIndexOffset: Int = 0,
delegateForTypeQualifiers: Lazy<JavaTypeQualifiersByElementType?>
) = LazyJavaResolverContext(
components,
typeParameterOwner?.let { LazyJavaTypeParameterResolver(this, containingDeclaration, it, typeParametersIndexOffset) }
?: typeParameterResolver,
delegateForTypeQualifiers
)
fun LazyJavaResolverContext.childForMethod(
containingDeclaration: DeclarationDescriptor,
typeParameterOwner: JavaTypeParameterListOwner,
typeParametersIndexOffset: Int = 0
) = this.child(LazyJavaTypeParameterResolver(this, containingDeclaration, typeParameterOwner, typeParametersIndexOffset))
) = child(containingDeclaration, typeParameterOwner, typeParametersIndexOffset, delegateForDefaultTypeQualifiers)
fun LazyJavaResolverContext.childForClassOrPackage(
containingDeclaration: ClassOrPackageFragmentDescriptor,
typeParameterOwner: JavaTypeParameterListOwner? = null,
typeParametersIndexOffset: Int = 0
) = child(
containingDeclaration, typeParameterOwner, typeParametersIndexOffset,
lazy(LazyThreadSafetyMode.NONE) { computeNewDefaultTypeQualifiers(containingDeclaration.annotations) }
)
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.load.java.components.JavaResolverCache
import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
import org.jetbrains.kotlin.load.java.lazy.replaceComponents
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
@@ -64,7 +64,7 @@ class LazyJavaClassDescriptor(
private val PUBLIC_METHOD_NAMES_IN_OBJECT = setOf("equals", "hashCode", "getClass", "wait", "notify", "notifyAll", "toString")
}
private val c: LazyJavaResolverContext = outerContext.child(this, jClass)
private val c: LazyJavaResolverContext = outerContext.childForClassOrPackage(this, jClass)
init {
c.components.javaResolverCache.recordClass(jClass, this)
@@ -37,7 +37,7 @@ import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.descriptors.copyValueParameters
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.childForMethod
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.types.toAttributes
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
@@ -86,6 +86,7 @@ class LazyJavaClassMemberScope(
}
c.components.signatureEnhancement.enhanceSignatures(
c,
result.ifEmpty { listOfNotNull(createDefaultConstructor()) }
).toList()
}
@@ -424,7 +425,7 @@ class LazyJavaClassMemberScope(
val getter = DescriptorFactory.createDefaultGetter(propertyDescriptor, Annotations.EMPTY)
propertyDescriptor.initialize(getter, null)
val returnType = givenType ?: computeMethodReturnType(method, annotations, c.child(propertyDescriptor, method))
val returnType = givenType ?: computeMethodReturnType(method, annotations, c.childForMethod(propertyDescriptor, method))
propertyDescriptor.setType(returnType, listOf(), getDispatchReceiverParameter(), null as KotlinType?)
getter.initialize(returnType)
@@ -511,7 +512,7 @@ class LazyJavaClassMemberScope(
)
val c = c.child(constructorDescriptor, constructor, typeParametersIndexOffset = classDescriptor.declaredTypeParameters.size)
val c = c.childForMethod(constructorDescriptor, constructor, typeParametersIndexOffset = classDescriptor.declaredTypeParameters.size)
val valueParameters = resolveValueParameters(c, constructorDescriptor, constructor.valueParameters)
val constructorTypeParameters =
classDescriptor.declaredTypeParameters +
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.java.structure.JavaPackage
@@ -31,9 +32,11 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.getValue
class LazyJavaPackageFragment(
private val c: LazyJavaResolverContext,
outerContext: LazyJavaResolverContext,
private val jPackage: JavaPackage
) : PackageFragmentDescriptorImpl(c.module, jPackage.fqName) {
) : PackageFragmentDescriptorImpl(outerContext.module, jPackage.fqName) {
private val c = outerContext.childForClassOrPackage(this)
internal val binaryClasses by c.storageManager.createLazyValue {
c.components.packageMapper.findPackageParts(fqName.asString()).mapNotNull { partName ->
val classId = ClassId(fqName, Name.identifier(partName))
@@ -49,10 +52,7 @@ class LazyJavaPackageFragment(
onRecursiveCall = listOf()
)
private val packageAnnotations = c.resolveAnnotations(jPackage)
// Test only method
fun getPackageAnnotations() = packageAnnotations
override val annotations = c.resolveAnnotations(jPackage)
internal fun getSubPackageFqNames(): List<FqName> = subPackages()
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.load.java.components.TypeUsage
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
import org.jetbrains.kotlin.load.java.descriptors.JavaPropertyDescriptor
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.child
import org.jetbrains.kotlin.load.java.lazy.childForMethod
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
import org.jetbrains.kotlin.load.java.lazy.types.LazyJavaTypeAttributes
import org.jetbrains.kotlin.load.java.structure.JavaArrayType
@@ -87,7 +87,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
computeNonDeclaredFunctions(result, name)
c.components.signatureEnhancement.enhanceSignatures(result).toList()
c.components.signatureEnhancement.enhanceSignatures(c, result).toList()
}
open protected fun JavaMethodDescriptor.isVisibleAsFunction() = true
@@ -114,7 +114,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
ownerDescriptor, annotations, method.name, c.components.sourceElementFactory.source(method)
)
val c = c.child(functionDescriptorImpl, method)
val c = c.childForMethod(functionDescriptorImpl, method)
val methodTypeParameters = method.typeParameters.map { p -> c.typeParameterResolver.resolveTypeParameter(p)!! }
val valueParameters = resolveValueParameters(c, functionDescriptorImpl, method.valueParameters)
@@ -246,7 +246,7 @@ abstract class LazyJavaScope(protected val c: LazyJavaResolverContext) : MemberS
if (DescriptorUtils.isAnnotationClass(ownerDescriptor))
properties.toList()
else
c.components.signatureEnhancement.enhanceSignatures(properties).toList()
c.components.signatureEnhancement.enhanceSignatures(c, properties).toList()
}
private fun resolveProperty(field: JavaField): PropertyDescriptor {
@@ -19,12 +19,17 @@ package org.jetbrains.kotlin.load.java.typeEnhancement
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
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.descriptors.annotations.composeAnnotations
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.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.computeNewDefaultTypeQualifiers
import org.jetbrains.kotlin.load.java.lazy.descriptors.isJavaField
import org.jetbrains.kotlin.load.kotlin.SignatureBuildingComponents
import org.jetbrains.kotlin.load.kotlin.computeJvmDescriptor
import org.jetbrains.kotlin.name.FqName
@@ -36,17 +41,40 @@ import org.jetbrains.kotlin.types.asFlexibleType
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.isFlexible
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.util.*
class SignatureEnhancement(private val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver) {
fun <D : CallableMemberDescriptor> enhanceSignatures(platformSignatures: Collection<D>): Collection<D> {
fun extractNullability(annotationDescriptor: AnnotationDescriptor): NullabilityQualifier? {
when (annotationDescriptor.annotationClass?.fqNameSafe) {
in NULLABLE_ANNOTATIONS -> return NullabilityQualifier.NULLABLE
in NOT_NULL_ANNOTATIONS -> return NullabilityQualifier.NOT_NULL
}
val typeQualifier =
annotationTypeQualifierResolver
.resolveTypeQualifierAnnotation(annotationDescriptor)
?.takeIf { it.annotationClass?.fqNameSafe == JAVAX_NONNULL_ANNOTATION }
?: return null
return typeQualifier.allValueArguments.values.singleOrNull()?.value?.let {
enumEntryDescriptor ->
if (enumEntryDescriptor !is ClassDescriptor) return@let null
if (enumEntryDescriptor.name.asString() == "ALWAYS") NullabilityQualifier.NOT_NULL else NullabilityQualifier.NULLABLE
} ?: NullabilityQualifier.NOT_NULL
}
fun <D : CallableMemberDescriptor> enhanceSignatures(c: LazyJavaResolverContext, platformSignatures: Collection<D>): Collection<D> {
return platformSignatures.map {
it.enhanceSignature()
it.enhanceSignature(c)
}
}
private fun <D : CallableMemberDescriptor> D.enhanceSignature(): D {
private fun <D : CallableMemberDescriptor> D.enhanceSignature(c: LazyJavaResolverContext): D {
val outerScopeQualifiers = c.computeNewDefaultTypeQualifiers(annotations)
// TODO type parameters
// TODO use new type parameters while enhancing other types
// TODO Propagation into generic type arguments
@@ -62,7 +90,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
typeContainer =
this.safeAs<FunctionDescriptor>()
?.getUserData(JavaMethodDescriptor.ORIGINAL_VALUE_PARAMETER_FOR_EXTENSION_RECEIVER),
isCovariant = false
isCovariant = false,
defaultTopLevelQualifiers =
outerScopeQualifiers
?.get(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER)
) { it.extensionReceiverParameter!!.type }.enhance()
else null
@@ -81,12 +112,28 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
val valueParameterEnhancements = valueParameters.map {
p ->
parts(typeContainer = p, isCovariant = false) { it.valueParameters[p.index].type }
parts(
typeContainer = p, isCovariant = false,
defaultTopLevelQualifiers =
outerScopeQualifiers
?.get(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER)
) { it.valueParameters[p.index].type }
.enhance(predefinedEnhancementInfo?.parametersInfo?.getOrNull(p.index))
}
val returnTypeEnhancement =
parts(typeContainer = this, isCovariant = true) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
parts(
typeContainer = this, isCovariant = true,
defaultTopLevelQualifiers =
outerScopeQualifiers?.get(
if (this.safeAs<PropertyDescriptor>()?.isJavaField == true)
AnnotationTypeQualifierResolver.QualifierApplicabilityType.FIELD
else
AnnotationTypeQualifierResolver.QualifierApplicabilityType.METHOD_RETURN_TYPE
)
) { it.returnType!! }.enhance(predefinedEnhancementInfo?.returnTypeInfo)
if ((receiverTypeEnhancement?.wereChanges ?: false)
|| returnTypeEnhancement.wereChanges || valueParameterEnhancements.any { it.wereChanges }) {
@@ -101,7 +148,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
private val typeContainer: Annotated?,
private val fromOverride: KotlinType,
private val fromOverridden: Collection<KotlinType>,
private val isCovariant: Boolean
private val isCovariant: Boolean,
private val defaultTopLevelQualifiers: JavaTypeQualifiers?
) {
fun enhance(predefined: TypeEnhancementInfo? = null): PartEnhancementResult {
val qualifiers = computeIndexedQualifiersForOverride()
@@ -152,7 +200,10 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
fun <T: Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
val nullability = composedAnnotation.extractNullability()
val defaultTypeQualifier = defaultTopLevelQualifiers?.takeIf { isHeadTypeConstructor }
val nullability =
composedAnnotation.extractNullability()
?: defaultTypeQualifier?.nullability
return JavaTypeQualifiers(
nullability,
@@ -168,28 +219,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
)
}
private fun Annotations.extractNullability(): NullabilityQualifier? {
for (annotationDescriptor in this) {
when (annotationDescriptor.annotationClass?.fqNameSafe) {
in NULLABLE_ANNOTATIONS -> return NullabilityQualifier.NULLABLE
in NOT_NULL_ANNOTATIONS -> return NullabilityQualifier.NOT_NULL
}
val typeQualifier =
annotationTypeQualifierResolver
.resolveTypeQualifierAnnotation(annotationDescriptor)
?.takeIf { it.annotationClass?.fqNameSafe == JAVAX_NONNULL_ANNOTATION }
?: continue
return typeQualifier.allValueArguments.values.singleOrNull()?.value?.let {
enumEntryDescriptor ->
if (enumEntryDescriptor !is ClassDescriptor) return@let null
if (enumEntryDescriptor.name.asString() == "ALWAYS") NullabilityQualifier.NOT_NULL else NullabilityQualifier.NULLABLE
} ?: NullabilityQualifier.NOT_NULL
}
return null
}
private fun Annotations.extractNullability(): NullabilityQualifier? =
this.firstNotNullResult(this@SignatureEnhancement::extractNullability)
private fun computeIndexedQualifiersForOverride(): (Int) -> JavaTypeQualifiers {
fun KotlinType.toIndexed(): List<KotlinType> {
@@ -292,6 +323,7 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
private fun <D : CallableMemberDescriptor> D.parts(
typeContainer: Annotated?,
isCovariant: Boolean,
defaultTopLevelQualifiers: JavaTypeQualifiers?,
collector: (D) -> KotlinType
): SignatureParts {
return SignatureParts(
@@ -301,7 +333,8 @@ class SignatureEnhancement(private val annotationTypeQualifierResolver: Annotati
@Suppress("UNCHECKED_CAST")
collector(it as D)
},
isCovariant
isCovariant,
defaultTopLevelQualifiers
)
}