From 8948023a26c62961e5b165aca34db010a15a6684 Mon Sep 17 00:00:00 2001 From: Denis Zharkov Date: Wed, 9 Aug 2017 18:25:29 +0700 Subject: [PATCH] Add built-in support for ParametersAre(Non)nullByDefault annotation #KT-19419 In Progress --- .../kotlin/load/java/lazy/context.kt | 49 ++++++++++++++++--- 1 file changed, 41 insertions(+), 8 deletions(-) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt index 1dbb527d521..d1303f3f875 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/context.kt @@ -18,6 +18,7 @@ package org.jetbrains.kotlin.load.java.lazy import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver @@ -31,6 +32,7 @@ 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.name.FqName import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter import org.jetbrains.kotlin.storage.StorageManager import java.util.* @@ -109,27 +111,58 @@ fun LazyJavaResolverContext.child( fun LazyJavaResolverContext.computeNewDefaultTypeQualifiers( additionalAnnotations: Annotations ): JavaTypeQualifiersByElementType? { - val typeQualifierDefaults = - additionalAnnotations.mapNotNull(components.annotationTypeQualifierResolver::resolveTypeQualifierDefaultAnnotation) + val nullabilityQualifiersWithApplicability = + additionalAnnotations.mapNotNull(this::extractDefaultNullabilityQualifier) - if (typeQualifierDefaults.isEmpty()) return defaultTypeQualifiers + if (nullabilityQualifiersWithApplicability.isEmpty()) return defaultTypeQualifiers - val nullabilityQualifiers = + val nullabilityQualifiersByType = 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 ((nullability, applicableTo) in nullabilityQualifiersWithApplicability) { for (applicabilityType in applicableTo) { - nullabilityQualifiers[applicabilityType] = nullability + nullabilityQualifiersByType[applicabilityType] = nullability wasUpdate = true } } - return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(nullabilityQualifiers) + return if (!wasUpdate) defaultTypeQualifiers else JavaTypeQualifiersByElementType(nullabilityQualifiersByType) } +private fun LazyJavaResolverContext.extractDefaultNullabilityQualifier( + annotationDescriptor: AnnotationDescriptor +): NullabilityQualifierWithApplicability? { + BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS[annotationDescriptor.fqName]?.let { return it } + + val (typeQualifier, applicability) = + components.annotationTypeQualifierResolver.resolveTypeQualifierDefaultAnnotation(annotationDescriptor) + ?: return null + + val nullability = components.signatureEnhancement.extractNullability(typeQualifier) ?: return null + + return NullabilityQualifierWithApplicability(nullability, applicability) +} + +data class NullabilityQualifierWithApplicability( + val nullabilityQualifier: NullabilityQualifier, + val qualifierApplicabilityTypes: Collection +) + +private val BUILT_IN_TYPE_QUALIFIER_DEFAULT_ANNOTATIONS = mapOf( + FqName("javax.annotation.ParametersAreNullableByDefault") to + NullabilityQualifierWithApplicability( + NullabilityQualifier.NULLABLE, + listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) + ), + FqName("javax.annotation.ParametersAreNonnullByDefault") to + NullabilityQualifierWithApplicability( + NullabilityQualifier.NOT_NULL, + listOf(AnnotationTypeQualifierResolver.QualifierApplicabilityType.VALUE_PARAMETER) + ) +) + fun LazyJavaResolverContext.replaceComponents( components: JavaResolverComponents ) = LazyJavaResolverContext(components, typeParameterResolver, delegateForDefaultTypeQualifiers)