Further simplify Java annotation resolution
Filter annotations by FQ name, get rid of unneeded properties, lazy values, static import some stuff
This commit is contained in:
+22
-1
@@ -21,10 +21,11 @@ import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation
|
|||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
import org.jetbrains.kotlin.load.java.structure.JavaAnnotation
|
||||||
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner
|
import org.jetbrains.kotlin.load.java.structure.JavaAnnotationOwner
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
|
||||||
class LazyJavaAnnotations(
|
class LazyJavaAnnotations(
|
||||||
private val c: LazyJavaResolverContext,
|
private val c: LazyJavaResolverContext,
|
||||||
val annotationOwner: JavaAnnotationOwner
|
private val annotationOwner: JavaAnnotationOwner
|
||||||
) : Annotations {
|
) : Annotations {
|
||||||
private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues {
|
private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues {
|
||||||
annotation: JavaAnnotation ->
|
annotation: JavaAnnotation ->
|
||||||
@@ -38,5 +39,25 @@ class LazyJavaAnnotations(
|
|||||||
override fun isEmpty() = !iterator().hasNext()
|
override fun isEmpty() = !iterator().hasNext()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class FilteredAnnotations(
|
||||||
|
private val delegate: Annotations,
|
||||||
|
private val fqNameFilter: (FqName) -> Boolean
|
||||||
|
) : Annotations {
|
||||||
|
override fun findAnnotation(fqName: FqName) =
|
||||||
|
if (fqNameFilter(fqName)) delegate.findAnnotation(fqName)
|
||||||
|
else null
|
||||||
|
|
||||||
|
override fun iterator() = delegate.sequence()
|
||||||
|
.filter { annotation ->
|
||||||
|
val descriptor = annotation.getType().getConstructor().getDeclarationDescriptor()
|
||||||
|
descriptor != null && DescriptorUtils.getFqName(descriptor).let { fqName ->
|
||||||
|
fqName.isSafe() && fqNameFilter(fqName.toSafe())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.iterator()
|
||||||
|
|
||||||
|
override fun isEmpty() = !iterator().hasNext()
|
||||||
|
}
|
||||||
|
|
||||||
fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations
|
fun LazyJavaResolverContext.resolveAnnotations(annotationsOwner: JavaAnnotationOwner): Annotations
|
||||||
= LazyJavaAnnotations(this, annotationsOwner)
|
= LazyJavaAnnotations(this, annotationsOwner)
|
||||||
|
|||||||
+3
-3
@@ -149,7 +149,7 @@ public abstract class LazyJavaMemberScope(
|
|||||||
protected fun computeMethodReturnType(method: JavaMethod, annotations: Annotations, c: LazyJavaResolverContext): JetType {
|
protected fun computeMethodReturnType(method: JavaMethod, annotations: Annotations, c: LazyJavaResolverContext): JetType {
|
||||||
val annotationMethod = method.getContainingClass().isAnnotationType()
|
val annotationMethod = method.getContainingClass().isAnnotationType()
|
||||||
val returnTypeAttrs = LazyJavaTypeAttributes(
|
val returnTypeAttrs = LazyJavaTypeAttributes(
|
||||||
c, method, TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations,
|
TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations,
|
||||||
allowFlexible = !annotationMethod,
|
allowFlexible = !annotationMethod,
|
||||||
isForAnnotationParameter = annotationMethod
|
isForAnnotationParameter = annotationMethod
|
||||||
)
|
)
|
||||||
@@ -172,7 +172,7 @@ public abstract class LazyJavaMemberScope(
|
|||||||
val (index, javaParameter) = pair
|
val (index, javaParameter) = pair
|
||||||
|
|
||||||
val annotations = c.resolveAnnotations(javaParameter)
|
val annotations = c.resolveAnnotations(javaParameter)
|
||||||
val typeUsage = LazyJavaTypeAttributes(c, javaParameter, TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, annotations)
|
val typeUsage = LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT, annotations)
|
||||||
val (outType, varargElementType) =
|
val (outType, varargElementType) =
|
||||||
if (javaParameter.isVararg()) {
|
if (javaParameter.isVararg()) {
|
||||||
val paramType = javaParameter.getType() as? JavaArrayType
|
val paramType = javaParameter.getType() as? JavaArrayType
|
||||||
@@ -282,7 +282,7 @@ public abstract class LazyJavaMemberScope(
|
|||||||
val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field))
|
val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field))
|
||||||
val propertyType = c.typeResolver.transformJavaType(
|
val propertyType = c.typeResolver.transformJavaType(
|
||||||
field.getType(),
|
field.getType(),
|
||||||
LazyJavaTypeAttributes(c, field, TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible)
|
LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible)
|
||||||
)
|
)
|
||||||
if ((!allowFlexible || !PLATFORM_TYPES) && finalStatic) {
|
if ((!allowFlexible || !PLATFORM_TYPES) && finalStatic) {
|
||||||
return TypeUtils.makeNotNullable(propertyType)
|
return TypeUtils.makeNotNullable(propertyType)
|
||||||
|
|||||||
+13
-23
@@ -20,10 +20,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
|||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationsImpl
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
|
||||||
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
import org.jetbrains.kotlin.load.java.components.TypeUsage
|
||||||
import org.jetbrains.kotlin.load.java.components.TypeUsage.*
|
import org.jetbrains.kotlin.load.java.components.TypeUsage.*
|
||||||
|
import org.jetbrains.kotlin.load.java.lazy.FilteredAnnotations
|
||||||
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext
|
||||||
import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver
|
import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver
|
||||||
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND
|
import org.jetbrains.kotlin.load.java.lazy.types.JavaTypeFlexibility.FLEXIBLE_LOWER_BOUND
|
||||||
@@ -34,7 +34,6 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
import org.jetbrains.kotlin.platform.JavaToKotlinClassMap
|
||||||
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
|
import org.jetbrains.kotlin.resolve.jvm.PLATFORM_TYPES
|
||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.storage.get
|
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.Variance.INVARIANT
|
import org.jetbrains.kotlin.types.Variance.INVARIANT
|
||||||
import org.jetbrains.kotlin.types.Variance.IN_VARIANCE
|
import org.jetbrains.kotlin.types.Variance.IN_VARIANCE
|
||||||
@@ -364,35 +363,26 @@ enum class JavaTypeFlexibility {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class LazyJavaTypeAttributes(
|
class LazyJavaTypeAttributes(
|
||||||
c: LazyJavaResolverContext,
|
|
||||||
val annotationOwner: JavaAnnotationOwner,
|
|
||||||
override val howThisTypeIsUsed: TypeUsage,
|
override val howThisTypeIsUsed: TypeUsage,
|
||||||
annotations: Annotations,
|
annotations: Annotations,
|
||||||
override val allowFlexible: Boolean = true,
|
override val allowFlexible: Boolean = true,
|
||||||
override val isForAnnotationParameter: Boolean = false
|
override val isForAnnotationParameter: Boolean = false
|
||||||
): JavaTypeAttributes {
|
): JavaTypeAttributes {
|
||||||
override val typeAnnotations: Annotations by c.storageManager.createLazyValue {
|
override val typeAnnotations = FilteredAnnotations(annotations) { it in ANNOTATIONS_COPIED_TO_TYPES }
|
||||||
AnnotationsImpl(JvmAnnotationNames.ANNOTATIONS_COPIED_TO_TYPES.map { fqName ->
|
|
||||||
annotations.findAnnotation(fqName)
|
|
||||||
}.filterNotNull())
|
|
||||||
}
|
|
||||||
|
|
||||||
override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage by c.storageManager.createLazyValue {
|
override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage get() =
|
||||||
if (annotations.isMarkedReadOnly() && !annotations.isMarkedMutable())
|
if (hasAnnotation(JETBRAINS_READONLY_ANNOTATION) && !hasAnnotation(JETBRAINS_MUTABLE_ANNOTATION))
|
||||||
TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT
|
TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT
|
||||||
else
|
else
|
||||||
TypeUsage.MEMBER_SIGNATURE_COVARIANT
|
TypeUsage.MEMBER_SIGNATURE_COVARIANT
|
||||||
}
|
|
||||||
|
|
||||||
override val isMarkedNotNull: Boolean by c.storageManager.createLazyValue {
|
override val isMarkedNotNull: Boolean get() = typeAnnotations.isMarkedNotNull()
|
||||||
annotationOwner.findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null
|
|
||||||
}
|
private fun hasAnnotation(fqName: FqName) = typeAnnotations.findAnnotation(fqName) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Annotations.isMarkedReadOnly() = findAnnotation(JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null
|
internal fun Annotations.isMarkedNotNull() = findAnnotation(JETBRAINS_NOT_NULL_ANNOTATION) != null
|
||||||
private fun Annotations.isMarkedMutable() = findAnnotation(JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION) != null
|
internal fun Annotations.isMarkedNullable() = findAnnotation(JETBRAINS_NULLABLE_ANNOTATION) != null
|
||||||
internal fun Annotations.isMarkedNotNull() = findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null
|
|
||||||
internal fun Annotations.isMarkedNullable() = findAnnotation(JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION) != null
|
|
||||||
|
|
||||||
fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParameter: Boolean = false) = object : JavaTypeAttributes {
|
fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParameter: Boolean = false) = object : JavaTypeAttributes {
|
||||||
override val howThisTypeIsUsed: TypeUsage = this@toAttributes
|
override val howThisTypeIsUsed: TypeUsage = this@toAttributes
|
||||||
|
|||||||
Reference in New Issue
Block a user