diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/annotationCheckers.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt similarity index 74% rename from compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/annotationCheckers.kt rename to compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt index 4537c7e393a..39dfe950449 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/annotationCheckers.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/FileClassAnnotationsChecker.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.isValidJavaFqName import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker @@ -31,35 +30,9 @@ import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention -import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm -object RepeatableAnnotationChecker: AdditionalAnnotationChecker { - override fun checkEntries(entries: List, actualTargets: List, trace: BindingTrace) { - val entryTypesWithAnnotations = hashMapOf>() - - for (entry in entries) { - val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue - val fqName = descriptor.fqName ?: continue - val classDescriptor = descriptor.annotationClass ?: continue - - val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() - val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(fqName) { arrayListOf() } - val duplicateAnnotation = useSiteTarget in existingTargetsForAnnotation - || (existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) }) - - if (duplicateAnnotation - && classDescriptor.isRepeatableAnnotation() - && classDescriptor.getAnnotationRetention() != KotlinRetention.SOURCE) { - trace.report(ErrorsJvm.NON_SOURCE_REPEATED_ANNOTATION.on(entry)) - } - - existingTargetsForAnnotation.add(useSiteTarget) - } - } -} - -object FileClassAnnotationsChecker: AdditionalAnnotationChecker { +object FileClassAnnotationsChecker : AdditionalAnnotationChecker { // JvmName & JvmMultifileClass annotations are applicable to multi-file class parts regardless of their retention. private val alwaysApplicable = hashSetOf(JvmFileClassUtil.JVM_NAME, JvmFileClassUtil.JVM_MULTIFILE_CLASS) 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 new file mode 100644 index 00000000000..621840289e2 --- /dev/null +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/checkers/RepeatableAnnotationChecker.kt @@ -0,0 +1,45 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.jvm.checkers + +import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget +import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention +import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker +import org.jetbrains.kotlin.resolve.BindingContext +import org.jetbrains.kotlin.resolve.BindingTrace +import org.jetbrains.kotlin.resolve.descriptorUtil.annotationClass +import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention +import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation +import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm + +object RepeatableAnnotationChecker : AdditionalAnnotationChecker { + override fun checkEntries(entries: List, actualTargets: List, trace: BindingTrace) { + val entryTypesWithAnnotations = hashMapOf>() + + for (entry in entries) { + val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue + val fqName = descriptor.fqName ?: continue + val classDescriptor = descriptor.annotationClass ?: continue + + val useSiteTarget = entry.useSiteTarget?.getAnnotationUseSiteTarget() + val existingTargetsForAnnotation = entryTypesWithAnnotations.getOrPut(fqName) { arrayListOf() } + val duplicateAnnotation = useSiteTarget in existingTargetsForAnnotation + || (existingTargetsForAnnotation.any { (it == null) != (useSiteTarget == null) }) + + if (duplicateAnnotation + && classDescriptor.isRepeatableAnnotation() + && classDescriptor.getAnnotationRetention() != KotlinRetention.SOURCE + ) { + trace.report(ErrorsJvm.NON_SOURCE_REPEATED_ANNOTATION.on(entry)) + } + + existingTargetsForAnnotation.add(useSiteTarget) + } + } +}