Forbid experimental markers on getter #KT-45845 Fixed

This commit is contained in:
Mikhail Glukhikh
2021-05-20 18:54:38 +03:00
committed by teamcityserver
parent 0a670bf055
commit bb9efab3c4
6 changed files with 65 additions and 12 deletions
@@ -286,6 +286,8 @@ public interface Errors {
DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<PsiElement> EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> EXPERIMENTAL_ANNOTATION_ON_GETTER = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
@@ -170,6 +170,8 @@ public class DefaultErrorMessages {
MAP.put(EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET, "Opt-in requirement marker annotation cannot be used on the following code elements: {0}. Please remove these targets", STRING);
MAP.put(EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION, "Opt-in requirement marker annotation cannot be used with SOURCE retention. Please replace retention with BINARY");
MAP.put(EXPERIMENTAL_ANNOTATION_ON_GETTER, "Opt-in requirement marker annotation cannot be used on getter. Please annotate property instead");
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS, "{0}", STRING);
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "{0}", STRING);
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.checkers
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
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.diagnostics.Errors
@@ -19,12 +20,15 @@ import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.KClassValue
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.utils.addToStdlib.safeAs
class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleDescriptor) : AdditionalAnnotationChecker {
private val WRONG_TARGETS_FOR_MARKER = setOf(KotlinTarget.EXPRESSION, KotlinTarget.FILE)
companion object {
private val WRONG_TARGETS_FOR_MARKER = setOf(KotlinTarget.EXPRESSION, KotlinTarget.FILE)
}
override fun checkEntries(
entries: List<KtAnnotationEntry>,
@@ -34,11 +38,11 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
var isAnnotatedWithExperimental = false
for (entry in entries) {
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry)
when (annotation?.fqName) {
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry) ?: continue
when (annotation.fqName) {
in ExperimentalUsageChecker.USE_EXPERIMENTAL_FQ_NAMES -> {
val annotationClasses =
annotation!!.allValueArguments[ExperimentalUsageChecker.USE_EXPERIMENTAL_ANNOTATION_CLASS]
annotation.allValueArguments[ExperimentalUsageChecker.USE_EXPERIMENTAL_ANNOTATION_CLASS]
.safeAs<ArrayValue>()?.value.orEmpty()
checkUseExperimentalUsage(annotationClasses, trace, entry)
}
@@ -46,6 +50,13 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
isAnnotatedWithExperimental = true
}
}
if (annotation.annotationClass?.annotations?.any { it.fqName in ExperimentalUsageChecker.EXPERIMENTAL_FQ_NAMES } == true) {
if (KotlinTarget.PROPERTY_GETTER in actualTargets ||
entry.useSiteTarget?.getAnnotationUseSiteTarget() == AnnotationUseSiteTarget.PROPERTY_GETTER
) {
trace.report(Errors.EXPERIMENTAL_ANNOTATION_ON_GETTER.on(entry))
}
}
}
if (isAnnotatedWithExperimental) {