Support foreign nullability annotations
#KT-10418 Fixed #KT-10594 Fixed
This commit is contained in:
+19
-3
@@ -19,11 +19,26 @@ package org.jetbrains.kotlin.load.java
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
val NULLABLE_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION
|
||||
JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION,
|
||||
FqName("android.support.annotation.Nullable"),
|
||||
FqName("org.eclipse.jdt.annotation.Nullable"),
|
||||
FqName("org.checkerframework.checker.nullness.qual.Nullable"),
|
||||
FqName("javax.annotation.Nullable"),
|
||||
FqName("javax.annotation.CheckForNull"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.CheckForNull"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.Nullable"),
|
||||
FqName("edu.umd.cs.findbugs.annotations.PossiblyNull")
|
||||
)
|
||||
|
||||
val JAVAX_NONNULL_ANNOTATION = FqName("javax.annotation.Nonnull")
|
||||
|
||||
val NOT_NULL_ANNOTATIONS = listOf(
|
||||
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION
|
||||
JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION,
|
||||
FqName("edu.umd.cs.findbugs.annotations.NonNull"),
|
||||
FqName("android.support.annotation.NonNull"),
|
||||
FqName("org.eclipse.jdt.annotation.NonNull"),
|
||||
FqName("org.checkerframework.checker.nullness.qual.NonNull"),
|
||||
FqName("lombok.NonNull")
|
||||
)
|
||||
|
||||
val READ_ONLY_ANNOTATIONS = listOf(
|
||||
@@ -37,5 +52,6 @@ val MUTABLE_ANNOTATIONS = listOf(
|
||||
// When these annotations appear on a declaration, they are copied to the _type_ of the declaration, becoming type annotations
|
||||
// See also DescriptorRendererOptions#excludedTypeAnnotationClasses
|
||||
val ANNOTATIONS_COPIED_TO_TYPES: Set<FqName> = listOf(
|
||||
NULLABLE_ANNOTATIONS, NOT_NULL_ANNOTATIONS, READ_ONLY_ANNOTATIONS, MUTABLE_ANNOTATIONS
|
||||
NULLABLE_ANNOTATIONS, NOT_NULL_ANNOTATIONS, READ_ONLY_ANNOTATIONS, MUTABLE_ANNOTATIONS,
|
||||
listOf(JAVAX_NONNULL_ANNOTATION)
|
||||
).flatMap { it }.toSet()
|
||||
|
||||
+25
-3
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.java.typeEnhancement
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||
import org.jetbrains.kotlin.load.java.*
|
||||
import org.jetbrains.kotlin.load.java.typeEnhancement.MutabilityQualifier.MUTABLE
|
||||
@@ -64,11 +65,32 @@ private fun KotlinType.extractQualifiers(): JavaTypeQualifiers {
|
||||
|
||||
private fun Annotations.extractQualifiers(): JavaTypeQualifiers {
|
||||
fun <T: Any> List<FqName>.ifPresent(qualifier: T) = if (any { findAnnotation(it) != null}) qualifier else null
|
||||
fun <T: Any> singleNotNull(x: T?, y: T?) = if (x == null || y == null) x ?: y else null
|
||||
|
||||
// These two overloads are just for sake of optimization as in most cases last parameter in second overload is null
|
||||
fun <T: Any> uniqueNotNull(x: T?, y: T?) = if (x == null || y == null || x == y) x ?: y else null
|
||||
fun <T: Any> uniqueNotNull(a: T?, b: T?, c: T?) =
|
||||
if (c == null)
|
||||
uniqueNotNull(a, b)
|
||||
else
|
||||
listOf(a, b, c).filterNotNull().toSet().singleOrNull()
|
||||
|
||||
// Javax/FundBugs NonNull annotation has parameter `when` that determines actual nullability
|
||||
fun FqName.extractQualifierFromAnnotationWithWhen(): NullabilityQualifier? {
|
||||
val annotationDescriptor = findAnnotation(this) ?: return null
|
||||
return annotationDescriptor.allValueArguments.values.singleOrNull()?.value?.let {
|
||||
enumEntryDescriptor ->
|
||||
if (enumEntryDescriptor !is ClassDescriptor) return@let null
|
||||
if (enumEntryDescriptor.name.asString() == "ALWAYS") NOT_NULL else NULLABLE
|
||||
} ?: NOT_NULL
|
||||
}
|
||||
|
||||
return JavaTypeQualifiers(
|
||||
singleNotNull(NULLABLE_ANNOTATIONS.ifPresent(NULLABLE), NOT_NULL_ANNOTATIONS.ifPresent(NOT_NULL)),
|
||||
singleNotNull(READ_ONLY_ANNOTATIONS.ifPresent(READ_ONLY), MUTABLE_ANNOTATIONS.ifPresent(MUTABLE))
|
||||
uniqueNotNull(
|
||||
NULLABLE_ANNOTATIONS.ifPresent(NULLABLE),
|
||||
NOT_NULL_ANNOTATIONS.ifPresent(NOT_NULL),
|
||||
JAVAX_NONNULL_ANNOTATION.extractQualifierFromAnnotationWithWhen()
|
||||
),
|
||||
uniqueNotNull(READ_ONLY_ANNOTATIONS.ifPresent(READ_ONLY), MUTABLE_ANNOTATIONS.ifPresent(MUTABLE))
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user