Disable JSR-305 annotations by default, introduce CLI argument

No package annotations are going to be loaded, and
TypeQualifierDefault/TypeQualifierNickname are no longer recognized by
default. Use the CLI argument "-Xload-jsr305-annotations" to enable this
behavior back

 #KT-10942
This commit is contained in:
Alexander Udalov
2017-07-07 13:33:42 +03:00
parent 522f67fda0
commit 127cd1295e
15 changed files with 119 additions and 76 deletions
@@ -19,6 +19,8 @@ package org.jetbrains.kotlin.load.java
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver.QualifierApplicabilityType
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver.TypeQualifierWithApplicability
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
@@ -31,28 +33,10 @@ private val TYPE_QUALIFIER_NICKNAME_FQNAME = FqName("javax.annotation.meta.TypeQ
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 =
storageManager.createMemoizedFunctionWithNullableValues(this::computeTypeQualifierNickname)
interface AnnotationTypeQualifierResolver {
fun resolveTypeQualifierAnnotation(annotationDescriptor: AnnotationDescriptor): AnnotationDescriptor?
private fun computeTypeQualifierNickname(classDescriptor: ClassDescriptor): AnnotationDescriptor? {
if (!classDescriptor.annotations.hasAnnotation(TYPE_QUALIFIER_NICKNAME_FQNAME)) return null
return classDescriptor.annotations.firstNotNullResult(this::resolveTypeQualifierAnnotation)
}
private fun resolveTypeQualifierNickname(classDescriptor: ClassDescriptor): AnnotationDescriptor? {
if (classDescriptor.kind != ClassKind.ANNOTATION_CLASS) return null
return resolvedNicknames(classDescriptor)
}
fun resolveTypeQualifierAnnotation(annotationDescriptor: AnnotationDescriptor): AnnotationDescriptor? {
val annotationClass = annotationDescriptor.annotationClass ?: return null
if (annotationClass.isAnnotatedWithTypeQualifier) return annotationDescriptor
return resolveTypeQualifierNickname(annotationClass)
}
fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability?
enum class QualifierApplicabilityType {
METHOD_RETURN_TYPE, VALUE_PARAMETER, FIELD, TYPE_USE
@@ -68,7 +52,37 @@ class AnnotationTypeQualifierResolver(storageManager: StorageManager) {
operator fun component2() = QualifierApplicabilityType.values().filter(this::isApplicableTo)
}
fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? {
object Empty : AnnotationTypeQualifierResolver {
override fun resolveTypeQualifierAnnotation(annotationDescriptor: AnnotationDescriptor): AnnotationDescriptor? = null
override fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? = null
}
}
class AnnotationTypeQualifierResolverImpl(storageManager: StorageManager) : AnnotationTypeQualifierResolver {
private val resolvedNicknames =
storageManager.createMemoizedFunctionWithNullableValues(this::computeTypeQualifierNickname)
private fun computeTypeQualifierNickname(classDescriptor: ClassDescriptor): AnnotationDescriptor? {
if (!classDescriptor.annotations.hasAnnotation(TYPE_QUALIFIER_NICKNAME_FQNAME)) return null
return classDescriptor.annotations.firstNotNullResult(this::resolveTypeQualifierAnnotation)
}
private fun resolveTypeQualifierNickname(classDescriptor: ClassDescriptor): AnnotationDescriptor? {
if (classDescriptor.kind != ClassKind.ANNOTATION_CLASS) return null
return resolvedNicknames(classDescriptor)
}
override fun resolveTypeQualifierAnnotation(annotationDescriptor: AnnotationDescriptor): AnnotationDescriptor? {
val annotationClass = annotationDescriptor.annotationClass ?: return null
if (annotationClass.isAnnotatedWithTypeQualifier) return annotationDescriptor
return resolveTypeQualifierNickname(annotationClass)
}
override fun resolveTypeQualifierDefaultAnnotation(annotationDescriptor: AnnotationDescriptor): TypeQualifierWithApplicability? {
val typeQualifierDefaultAnnotatedClass =
annotationDescriptor.annotationClass?.takeIf { it.annotations.hasAnnotation(TYPE_QUALIFIER_DEFAULT_FQNAME) }
?: return null
@@ -26,7 +26,7 @@ class LazyJavaPackageFragmentProvider(
components: JavaResolverComponents
) : PackageFragmentProvider {
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY) { null }
private val c = LazyJavaResolverContext(components, TypeParameterResolver.EMPTY, lazyOf(null))
private val packageFragments: MemoizedFunctionToNullable<FqName, LazyJavaPackageFragment> =
c.storageManager.createMemoizedFunctionWithNullableValues {
@@ -18,7 +18,9 @@ package org.jetbrains.kotlin.load.java.lazy.descriptors
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.load.java.AnnotationTypeQualifierResolver
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
import org.jetbrains.kotlin.load.java.lazy.childForClassOrPackage
import org.jetbrains.kotlin.load.java.lazy.resolveAnnotations
@@ -52,7 +54,10 @@ class LazyJavaPackageFragment(
onRecursiveCall = listOf()
)
override val annotations = c.resolveAnnotations(jPackage)
override val annotations =
// Do not resolve package annotations if JSR-305 is disabled
if (c.components.annotationTypeQualifierResolver == AnnotationTypeQualifierResolver.Empty) Annotations.EMPTY
else c.resolveAnnotations(jPackage)
internal fun getSubPackageFqNames(): List<FqName> = subPackages()
@@ -48,16 +48,18 @@ import java.util.*
class SignatureEnhancement(private val annotationTypeQualifierResolver: AnnotationTypeQualifierResolver) {
fun extractNullability(annotationDescriptor: AnnotationDescriptor): NullabilityQualifier? {
when (annotationDescriptor.annotationClass?.fqNameSafe) {
val annotationFqName = annotationDescriptor.annotationClass?.fqNameSafe ?: return null
when (annotationFqName) {
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
when {
annotationFqName == JAVAX_NONNULL_ANNOTATION -> annotationDescriptor
else -> annotationTypeQualifierResolver.resolveTypeQualifierAnnotation(annotationDescriptor)
?.takeIf { it.annotationClass?.fqNameSafe == JAVAX_NONNULL_ANNOTATION }
} ?: return null
val enumEntryDescriptor =
typeQualifier.allValueArguments.values.singleOrNull()?.value