diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaAnnotations.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaAnnotations.kt index 65952cc154c..03bb1e0e57d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaAnnotations.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/LazyJavaAnnotations.kt @@ -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.JavaAnnotationOwner import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.resolve.DescriptorUtils class LazyJavaAnnotations( private val c: LazyJavaResolverContext, - val annotationOwner: JavaAnnotationOwner + private val annotationOwner: JavaAnnotationOwner ) : Annotations { private val annotationDescriptors = c.storageManager.createMemoizedFunctionWithNullableValues { annotation: JavaAnnotation -> @@ -38,5 +39,25 @@ class LazyJavaAnnotations( 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 = LazyJavaAnnotations(this, annotationsOwner) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt index 01271ae8705..42c4f0fce2d 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaMemberScope.kt @@ -149,7 +149,7 @@ public abstract class LazyJavaMemberScope( protected fun computeMethodReturnType(method: JavaMethod, annotations: Annotations, c: LazyJavaResolverContext): JetType { val annotationMethod = method.getContainingClass().isAnnotationType() val returnTypeAttrs = LazyJavaTypeAttributes( - c, method, TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations, + TypeUsage.MEMBER_SIGNATURE_COVARIANT, annotations, allowFlexible = !annotationMethod, isForAnnotationParameter = annotationMethod ) @@ -172,7 +172,7 @@ public abstract class LazyJavaMemberScope( val (index, javaParameter) = pair 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) = if (javaParameter.isVararg()) { val paramType = javaParameter.getType() as? JavaArrayType @@ -282,7 +282,7 @@ public abstract class LazyJavaMemberScope( val allowFlexible = PLATFORM_TYPES && !(finalStatic && c.javaPropertyInitializerEvaluator.isNotNullCompileTimeConstant(field)) val propertyType = c.typeResolver.transformJavaType( field.getType(), - LazyJavaTypeAttributes(c, field, TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible) + LazyJavaTypeAttributes(TypeUsage.MEMBER_SIGNATURE_INVARIANT, annotations, allowFlexible) ) if ((!allowFlexible || !PLATFORM_TYPES) && finalStatic) { return TypeUtils.makeNotNullable(propertyType) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt index 4291436540c..ce9c59698fe 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/types/LazyJavaTypeResolver.kt @@ -20,10 +20,10 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor 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.lazy.FilteredAnnotations import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext import org.jetbrains.kotlin.load.java.lazy.TypeParameterResolver 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.resolve.jvm.PLATFORM_TYPES import org.jetbrains.kotlin.resolve.scopes.JetScope -import org.jetbrains.kotlin.storage.get import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.Variance.INVARIANT import org.jetbrains.kotlin.types.Variance.IN_VARIANCE @@ -364,35 +363,26 @@ enum class JavaTypeFlexibility { } class LazyJavaTypeAttributes( - c: LazyJavaResolverContext, - val annotationOwner: JavaAnnotationOwner, override val howThisTypeIsUsed: TypeUsage, annotations: Annotations, override val allowFlexible: Boolean = true, override val isForAnnotationParameter: Boolean = false ): JavaTypeAttributes { - override val typeAnnotations: Annotations by c.storageManager.createLazyValue { - AnnotationsImpl(JvmAnnotationNames.ANNOTATIONS_COPIED_TO_TYPES.map { fqName -> - annotations.findAnnotation(fqName) - }.filterNotNull()) - } + override val typeAnnotations = FilteredAnnotations(annotations) { it in ANNOTATIONS_COPIED_TO_TYPES } - override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage by c.storageManager.createLazyValue { - if (annotations.isMarkedReadOnly() && !annotations.isMarkedMutable()) - TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT - else - TypeUsage.MEMBER_SIGNATURE_COVARIANT - } + override val howThisTypeIsUsedAccordingToAnnotations: TypeUsage get() = + if (hasAnnotation(JETBRAINS_READONLY_ANNOTATION) && !hasAnnotation(JETBRAINS_MUTABLE_ANNOTATION)) + TypeUsage.MEMBER_SIGNATURE_CONTRAVARIANT + else + TypeUsage.MEMBER_SIGNATURE_COVARIANT - override val isMarkedNotNull: Boolean by c.storageManager.createLazyValue { - annotationOwner.findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null - } + override val isMarkedNotNull: Boolean get() = typeAnnotations.isMarkedNotNull() + + private fun hasAnnotation(fqName: FqName) = typeAnnotations.findAnnotation(fqName) != null } -private fun Annotations.isMarkedReadOnly() = findAnnotation(JvmAnnotationNames.JETBRAINS_READONLY_ANNOTATION) != null -private fun Annotations.isMarkedMutable() = findAnnotation(JvmAnnotationNames.JETBRAINS_MUTABLE_ANNOTATION) != null -internal fun Annotations.isMarkedNotNull() = findAnnotation(JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION) != null -internal fun Annotations.isMarkedNullable() = findAnnotation(JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION) != null +internal fun Annotations.isMarkedNotNull() = findAnnotation(JETBRAINS_NOT_NULL_ANNOTATION) != null +internal fun Annotations.isMarkedNullable() = findAnnotation(JETBRAINS_NULLABLE_ANNOTATION) != null fun TypeUsage.toAttributes(allowFlexible: Boolean = true, isForAnnotationParameter: Boolean = false) = object : JavaTypeAttributes { override val howThisTypeIsUsed: TypeUsage = this@toAttributes