diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java index f9d75fe5b9a..c80b0cff0f9 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/AnnotationCodegen.java @@ -297,7 +297,7 @@ public abstract class AnnotationCodegen { Map annotationTargetMap = annotationTargetMaps.get(typeMapper.getJvmTarget()); if (annotationTargetMap == null) throw new AssertionError("No annotation target map for JVM target " + typeMapper.getJvmTarget()); - Set targets = AnnotationChecker.Companion.applicableTargetSet(classDescriptor); + Set targets = AnnotationChecker.Companion.applicableTargetSetFromTargetAnnotationOrNull(classDescriptor); Set javaTargets; if (targets == null) { javaTargets = getJavaTargetList(classDescriptor); diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt index eae5816c4b9..9a4950e4999 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt @@ -50,7 +50,7 @@ object FileClassAnnotationsChecker : AdditionalAnnotationChecker { val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue val classDescriptor = descriptor.annotationClass ?: continue // This check matters for the applicable annotations only. - val applicableTargets = AnnotationChecker.applicableTargetSet(classDescriptor) + val applicableTargets = AnnotationChecker.applicableTargetSetFromTargetAnnotationOrNull(classDescriptor) if (applicableTargets == null || !applicableTargets.contains(KotlinTarget.FILE)) continue fileAnnotationsToCheck.add(Pair(entry, classDescriptor)) } diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/RepeatableAnnotationChecker.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/RepeatableAnnotationChecker.kt index ffe845d5ed9..d049b5ceb12 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/RepeatableAnnotationChecker.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/RepeatableAnnotationChecker.kt @@ -205,8 +205,8 @@ class RepeatableAnnotationChecker( annotationClass: ClassDescriptor, reportOn: KtAnnotationEntry, ): Diagnostic? { - val annotationTargets = AnnotationChecker.applicableTargetSet(annotationClass) ?: KotlinTarget.DEFAULT_TARGET_SET - val containerTargets = AnnotationChecker.applicableTargetSet(containerClass) ?: KotlinTarget.DEFAULT_TARGET_SET + val annotationTargets = AnnotationChecker.applicableTargetSet(annotationClass) + val containerTargets = AnnotationChecker.applicableTargetSet(containerClass) // See https://docs.oracle.com/javase/specs/jls/se16/html/jls-9.html#jls-9.6.3. // (TBH, the rules about TYPE/TYPE_USE and TYPE_PARAMETER/TYPE_USE don't seem to make a lot of sense, but it's JLS diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt index d3d0d62a634..125fbf81cdf 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/AnnotationChecker.kt @@ -297,16 +297,21 @@ class AnnotationChecker( val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET // For descriptor with error type, all targets are considered as possible if (descriptor.type.isError) return KotlinTarget.ALL_TARGET_SET - return descriptor.annotationClass?.let(this::applicableTargetSet) ?: KotlinTarget.DEFAULT_TARGET_SET + return descriptor.annotationClass?.let(this::applicableTargetSetFromTargetAnnotationOrNull) ?: KotlinTarget.DEFAULT_TARGET_SET } @JvmStatic fun applicableTargetSet(descriptor: AnnotationDescriptor): Set { val classDescriptor = descriptor.annotationClass ?: return emptySet() - return applicableTargetSet(classDescriptor) ?: KotlinTarget.DEFAULT_TARGET_SET + return applicableTargetSet(classDescriptor) } - fun applicableTargetSet(classDescriptor: ClassDescriptor): Set? { + fun applicableTargetSet(classDescriptor: ClassDescriptor): Set { + val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(StandardNames.FqNames.target) + return targetEntryDescriptor?.let { loadAnnotationTargets(it) } ?: KotlinTarget.DEFAULT_TARGET_SET + } + + fun applicableTargetSetFromTargetAnnotationOrNull(classDescriptor: ClassDescriptor): Set? { val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(StandardNames.FqNames.target) ?: return null return loadAnnotationTargets(targetEntryDescriptor) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/AnnotationClassTargetAndRetentionChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/AnnotationClassTargetAndRetentionChecker.kt index 0defde9809c..cf91a2e5dca 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/AnnotationClassTargetAndRetentionChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/AnnotationClassTargetAndRetentionChecker.kt @@ -7,7 +7,6 @@ package org.jetbrains.kotlin.resolve.checkers import com.intellij.psi.PsiElement import org.jetbrains.kotlin.builtins.StandardNames -import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor @@ -27,7 +26,7 @@ class AnnotationClassTargetAndRetentionChecker : DeclarationChecker { if (declaration !is KtClassOrObject) return if (!DescriptorUtils.isAnnotationClass(descriptor)) return - val targets = AnnotationChecker.applicableTargetSet(descriptor) ?: return + val targets = AnnotationChecker.applicableTargetSetFromTargetAnnotationOrNull(descriptor) ?: return val retention = descriptor.getAnnotationRetention() ?: KotlinRetention.RUNTIME if (targets.contains(KotlinTarget.EXPRESSION) && retention != KotlinRetention.SOURCE) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalMarkerDeclarationAnnotationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalMarkerDeclarationAnnotationChecker.kt index 239c6323cd9..f72893a665b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalMarkerDeclarationAnnotationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalMarkerDeclarationAnnotationChecker.kt @@ -59,7 +59,7 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD } val annotationClass = annotation.annotationClass ?: continue if (annotationClass.annotations.any { it.fqName in OptInNames.EXPERIMENTAL_FQ_NAMES }) { - val applicableTargets = AnnotationChecker.applicableTargetSet(annotationClass) ?: KotlinTarget.DEFAULT_TARGET_SET + val applicableTargets = AnnotationChecker.applicableTargetSet(annotationClass) val possibleTargets = applicableTargets.intersect(actualTargets) val annotationUseSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() if (PROPERTY_GETTER in possibleTargets ||