diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java index 1895fc09685..ea6d1a4e008 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/JvmAnnotationNames.java @@ -16,16 +16,10 @@ package org.jetbrains.kotlin.load.java; -import org.jetbrains.annotations.NotNull; -import org.jetbrains.kotlin.name.ClassId; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.jvm.JvmClassName; -import java.util.Arrays; -import java.util.HashSet; -import java.util.Set; - public final class JvmAnnotationNames { public static final FqName METADATA_FQ_NAME = new FqName("kotlin.Metadata"); public static final String METADATA_DESC = "L" + JvmClassName.byFqNameWithoutInnerClasses(METADATA_FQ_NAME).getInternalName() + ";"; @@ -36,13 +30,8 @@ public final class JvmAnnotationNames { public static final String METADATA_DATA_FIELD_NAME = "d1"; public static final String METADATA_STRINGS_FIELD_NAME = "d2"; public static final String METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME = "xs"; - public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value"); - public static final Name DEPRECATED_ANNOTATION_MESSAGE = Name.identifier("message"); - public static final Name TARGET_ANNOTATION_MEMBER_NAME = Name.identifier("allowedTargets"); - public static final FqName TARGET_ANNOTATION = new FqName("java.lang.annotation.Target"); - public static final FqName RETENTION_ANNOTATION = new FqName("java.lang.annotation.Retention"); - public static final FqName DOCUMENTED_ANNOTATION = new FqName("java.lang.annotation.Documented"); + public static final Name DEFAULT_ANNOTATION_MEMBER_NAME = Name.identifier("value"); public static final FqName JETBRAINS_NOT_NULL_ANNOTATION = new FqName("org.jetbrains.annotations.NotNull"); public static final FqName JETBRAINS_NULLABLE_ANNOTATION = new FqName("org.jetbrains.annotations.Nullable"); @@ -55,30 +44,6 @@ public final class JvmAnnotationNames { public static final FqName ENHANCED_NULLABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedNullability"); public static final FqName ENHANCED_MUTABILITY_ANNOTATION = new FqName("kotlin.jvm.internal.EnhancedMutability"); - private static final Set NULLABILITY_ANNOTATIONS = new HashSet(); - private static final Set SPECIAL_META_ANNOTATIONS = new HashSet(); - - static { - for (FqName fqName : Arrays.asList(JETBRAINS_NOT_NULL_ANNOTATION, JETBRAINS_NULLABLE_ANNOTATION)) { - NULLABILITY_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName)); - } - - for (FqName fqName : Arrays.asList(TARGET_ANNOTATION, RETENTION_ANNOTATION, DOCUMENTED_ANNOTATION)) { - SPECIAL_META_ANNOTATIONS.add(JvmClassName.byFqNameWithoutInnerClasses(fqName)); - } - } - - public static boolean isSpecialAnnotation(@NotNull ClassId classId, boolean javaSpecificAnnotationsAreSpecial) { - if (classId.asSingleFqName().equals(METADATA_FQ_NAME)) return true; - - if (javaSpecificAnnotationsAreSpecial) { - JvmClassName className = JvmClassName.byClassId(classId); - if (NULLABILITY_ANNOTATIONS.contains(className) || SPECIAL_META_ANNOTATIONS.contains(className)) return true; - } - - return false; - } - private JvmAnnotationNames() { } } diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt index 1ba8c4926a2..8e0e4dc6e4c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/components/JavaAnnotationMapper.kt @@ -23,18 +23,21 @@ import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget -import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext -import org.jetbrains.kotlin.load.java.lazy.descriptors.resolveAnnotation +import org.jetbrains.kotlin.load.java.lazy.descriptors.LazyJavaAnnotationDescriptor import org.jetbrains.kotlin.load.java.structure.* import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.FqName -import org.jetbrains.kotlin.resolve.constants.* +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.resolve.constants.ArrayValue +import org.jetbrains.kotlin.resolve.constants.ConstantValue +import org.jetbrains.kotlin.resolve.constants.ConstantValueFactory +import org.jetbrains.kotlin.resolve.constants.EnumValue import org.jetbrains.kotlin.types.ErrorUtils import java.lang.annotation.Documented import java.lang.annotation.Retention import java.lang.annotation.Target -import java.util.EnumSet +import java.util.* object JavaAnnotationMapper { @@ -45,6 +48,9 @@ object JavaAnnotationMapper { // Java8-specific thing private val JAVA_REPEATABLE_FQ_NAME = FqName("java.lang.annotation.Repeatable") + internal val DEPRECATED_ANNOTATION_MESSAGE = Name.identifier("message") + internal val TARGET_ANNOTATION_ALLOWED_TARGETS = Name.identifier("allowedTargets") + fun mapOrResolveJavaAnnotation(annotation: JavaAnnotation, c: LazyJavaResolverContext): AnnotationDescriptor? = when (annotation.classId) { ClassId.topLevel(JAVA_TARGET_FQ_NAME) -> JavaTargetAnnotationDescriptor(annotation, c) @@ -52,7 +58,7 @@ object JavaAnnotationMapper { ClassId.topLevel(JAVA_REPEATABLE_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, c.module.builtIns.repeatableAnnotation) ClassId.topLevel(JAVA_DOCUMENTED_FQ_NAME) -> JavaAnnotationDescriptor(c, annotation, c.module.builtIns.mustBeDocumentedAnnotation) ClassId.topLevel(JAVA_DEPRECATED_FQ_NAME) -> null - else -> c.resolveAnnotation(annotation) + else -> LazyJavaAnnotationDescriptor(c, annotation) } fun findMappedJavaAnnotation(kotlinName: FqName, @@ -113,7 +119,7 @@ class JavaDeprecatedAnnotationDescriptor( private val valueArguments = c.storageManager.createLazyValue { val parameterDescriptor = valueParameters.firstOrNull { - it.name == JvmAnnotationNames.DEPRECATED_ANNOTATION_MESSAGE + it.name == JavaAnnotationMapper.DEPRECATED_ANNOTATION_MESSAGE } parameterDescriptor?.let { mapOf(it to ConstantValueFactory(c.module.builtIns).createConstantValue("Deprecated in Java")) } ?: emptyMap() } @@ -175,17 +181,18 @@ object JavaAnnotationTargetMapper { // Map arguments: java.lang.annotation.Target -> kotlin.annotation.Target val kotlinTargets = arguments.filterIsInstance() .flatMap { mapJavaTargetArgumentByName(it.resolve()?.name?.asString()) } - .map { builtIns.getAnnotationTargetEnumEntry(it) } - .filterNotNull() + .mapNotNull { builtIns.getAnnotationTargetEnumEntry(it) } .map { EnumValue(it) } - val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName(JvmAnnotationNames.TARGET_ANNOTATION_MEMBER_NAME, - builtIns.targetAnnotation) + val parameterDescriptor = DescriptorResolverUtils.getAnnotationParameterByName( + JavaAnnotationMapper.TARGET_ANNOTATION_ALLOWED_TARGETS, builtIns.targetAnnotation + ) return ArrayValue(kotlinTargets, parameterDescriptor?.type ?: ErrorUtils.createErrorType("Error: AnnotationTarget[]"), builtIns) } - private val retentionNameList = mapOf("RUNTIME" to KotlinRetention.RUNTIME, - "CLASS" to KotlinRetention.BINARY, - "SOURCE" to KotlinRetention.SOURCE + private val retentionNameList = mapOf( + "RUNTIME" to KotlinRetention.RUNTIME, + "CLASS" to KotlinRetention.BINARY, + "SOURCE" to KotlinRetention.SOURCE ) fun mapJavaRetentionArgument(element: JavaAnnotationArgument, builtIns: KotlinBuiltIns): ConstantValue<*>? { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt index a675cda1392..f4c18258ec4 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/lazy/descriptors/LazyJavaAnnotationDescriptor.kt @@ -20,10 +20,8 @@ import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.EmptyPackageFragmentDescriptor -import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.load.java.JvmAnnotationNames.DEFAULT_ANNOTATION_MEMBER_NAME -import org.jetbrains.kotlin.load.java.JvmAnnotationNames.isSpecialAnnotation import org.jetbrains.kotlin.load.java.components.DescriptorResolverUtils import org.jetbrains.kotlin.load.java.components.TypeUsage import org.jetbrains.kotlin.load.java.lazy.LazyJavaResolverContext @@ -40,12 +38,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.utils.keysToMapExceptNulls -fun LazyJavaResolverContext.resolveAnnotation(annotation: JavaAnnotation): LazyJavaAnnotationDescriptor? { - val classId = annotation.classId - if (classId == null || isSpecialAnnotation(classId, false)) return null - return LazyJavaAnnotationDescriptor(this, annotation) -} - class LazyJavaAnnotationDescriptor( private val c: LazyJavaResolverContext, val javaAnnotation: JavaAnnotation @@ -105,10 +97,8 @@ class LazyJavaAnnotationDescriptor( } } - private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): ConstantValue<*>? { - val descriptor = c.resolveAnnotation(javaAnnotation) ?: return null - - return factory.createAnnotationValue(descriptor) + private fun resolveFromAnnotation(javaAnnotation: JavaAnnotation): ConstantValue<*> { + return factory.createAnnotationValue(LazyJavaAnnotationDescriptor(c, javaAnnotation)) } private fun resolveFromArray(argumentName: Name, elements: List): ConstantValue<*>? { diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt index 5f90514938d..1fe8ead920c 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/kotlin/AbstractBinaryClassAnnotationAndConstantLoader.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAnnotationNames import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.deserialization.* @@ -59,7 +60,7 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader ): KotlinJvmBinaryClass.AnnotationArgumentVisitor? { - if (JvmAnnotationNames.isSpecialAnnotation(annotationClassId, true)) return null + if (annotationClassId in SPECIAL_ANNOTATIONS) return null return loadAnnotation(annotationClassId, source, result) } @@ -334,4 +335,15 @@ abstract class AbstractBinaryClassAnnotationAndConstantLoader>, val propertyConstants: Map ) + + private companion object { + val SPECIAL_ANNOTATIONS = listOf( + JvmAnnotationNames.METADATA_FQ_NAME, + JvmAnnotationNames.JETBRAINS_NOT_NULL_ANNOTATION, + JvmAnnotationNames.JETBRAINS_NULLABLE_ANNOTATION, + FqName("java.lang.annotation.Target"), + FqName("java.lang.annotation.Retention"), + FqName("java.lang.annotation.Documented") + ).map(ClassId::topLevel).toSet() + } }