Forbid experimental markers on getter #KT-45845 Fixed
This commit is contained in:
committed by
teamcityserver
parent
0a670bf055
commit
bb9efab3c4
@@ -286,6 +286,8 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory0<PsiElement> EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION = DiagnosticFactory0.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 = DiagnosticFactory1.create(WARNING);
|
||||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
||||||
|
|
||||||
|
|||||||
+2
@@ -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_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_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, "{0}", STRING);
|
||||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "{0}", STRING);
|
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "{0}", STRING);
|
||||||
|
|
||||||
|
|||||||
+15
-4
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.resolve.checkers
|
|||||||
import org.jetbrains.kotlin.builtins.StandardNames
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
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.KotlinRetention
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors
|
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.ArrayValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
import org.jetbrains.kotlin.resolve.constants.ConstantValue
|
||||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
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.fqNameSafe
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAnnotationRetention
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleDescriptor) : AdditionalAnnotationChecker {
|
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(
|
override fun checkEntries(
|
||||||
entries: List<KtAnnotationEntry>,
|
entries: List<KtAnnotationEntry>,
|
||||||
@@ -34,11 +38,11 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
|
|||||||
var isAnnotatedWithExperimental = false
|
var isAnnotatedWithExperimental = false
|
||||||
|
|
||||||
for (entry in entries) {
|
for (entry in entries) {
|
||||||
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry)
|
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry) ?: continue
|
||||||
when (annotation?.fqName) {
|
when (annotation.fqName) {
|
||||||
in ExperimentalUsageChecker.USE_EXPERIMENTAL_FQ_NAMES -> {
|
in ExperimentalUsageChecker.USE_EXPERIMENTAL_FQ_NAMES -> {
|
||||||
val annotationClasses =
|
val annotationClasses =
|
||||||
annotation!!.allValueArguments[ExperimentalUsageChecker.USE_EXPERIMENTAL_ANNOTATION_CLASS]
|
annotation.allValueArguments[ExperimentalUsageChecker.USE_EXPERIMENTAL_ANNOTATION_CLASS]
|
||||||
.safeAs<ArrayValue>()?.value.orEmpty()
|
.safeAs<ArrayValue>()?.value.orEmpty()
|
||||||
checkUseExperimentalUsage(annotationClasses, trace, entry)
|
checkUseExperimentalUsage(annotationClasses, trace, entry)
|
||||||
}
|
}
|
||||||
@@ -46,6 +50,13 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
|
|||||||
isAnnotatedWithExperimental = true
|
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) {
|
if (isAnnotatedWithExperimental) {
|
||||||
|
|||||||
+17
-3
@@ -7,7 +7,7 @@ import kotlin.annotation.AnnotationTarget.*
|
|||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
|
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
|
||||||
PROPERTY_GETTER, PROPERTY_SETTER, TYPE, TYPEALIAS)
|
PROPERTY_SETTER, TYPE, TYPEALIAS)
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class E1
|
annotation class E1
|
||||||
|
|
||||||
@@ -21,6 +21,20 @@ annotation class E2
|
|||||||
annotation class E3
|
annotation class E3
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(FILE, EXPRESSION)
|
@Target(PROPERTY_GETTER)
|
||||||
@Retention(AnnotationRetention.SOURCE)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class E4
|
annotation class E4
|
||||||
|
|
||||||
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
|
@Target(PROPERTY_SETTER)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
annotation class E5
|
||||||
|
|
||||||
|
var some: Int
|
||||||
|
@E4
|
||||||
|
get() = 42
|
||||||
|
@E5
|
||||||
|
set(value) {}
|
||||||
|
|
||||||
|
@get:E4
|
||||||
|
val another: Int = 42
|
||||||
|
|||||||
+18
-3
@@ -7,7 +7,7 @@ import kotlin.annotation.AnnotationTarget.*
|
|||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
|
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
|
||||||
PROPERTY_GETTER, PROPERTY_SETTER, TYPE, TYPEALIAS)
|
PROPERTY_SETTER, TYPE, TYPEALIAS)
|
||||||
@Retention(AnnotationRetention.BINARY)
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class E1
|
annotation class E1
|
||||||
|
|
||||||
@@ -21,6 +21,21 @@ annotation class E2
|
|||||||
annotation class E3
|
annotation class E3
|
||||||
|
|
||||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(FILE, EXPRESSION)<!>
|
@Target(PROPERTY_GETTER)
|
||||||
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_RETENTION!>@Retention(AnnotationRetention.SOURCE)<!>
|
@Retention(AnnotationRetention.BINARY)
|
||||||
annotation class E4
|
annotation class E4
|
||||||
|
|
||||||
|
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||||
|
@Target(PROPERTY_SETTER)
|
||||||
|
@Retention(AnnotationRetention.BINARY)
|
||||||
|
annotation class E5
|
||||||
|
|
||||||
|
var some: Int
|
||||||
|
<!EXPERIMENTAL_ANNOTATION_ON_GETTER!>@E4<!>
|
||||||
|
get() = 42
|
||||||
|
@E5
|
||||||
|
set(value) {}
|
||||||
|
|
||||||
|
<!EXPERIMENTAL_ANNOTATION_ON_GETTER!>@get:E4<!>
|
||||||
|
val another: Int = 42
|
||||||
|
|
||||||
|
|||||||
+11
-2
@@ -1,8 +1,10 @@
|
|||||||
package
|
package
|
||||||
|
|
||||||
package api {
|
package api {
|
||||||
|
@get:api.E4 public val another: kotlin.Int = 42
|
||||||
|
@get:api.E4 @set:api.E5 public var some: kotlin.Int
|
||||||
|
|
||||||
@kotlin.RequiresOptIn(level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_GETTER, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.TYPE, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final annotation class E1 : kotlin.Annotation {
|
@kotlin.RequiresOptIn(level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.CLASS, AnnotationTarget.ANNOTATION_CLASS, AnnotationTarget.TYPE_PARAMETER, AnnotationTarget.PROPERTY, AnnotationTarget.FIELD, AnnotationTarget.LOCAL_VARIABLE, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY_SETTER, AnnotationTarget.TYPE, AnnotationTarget.TYPEALIAS}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final annotation class E1 : kotlin.Annotation {
|
||||||
public constructor E1()
|
public constructor E1()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
@@ -23,10 +25,17 @@ package api {
|
|||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
@kotlin.RequiresOptIn(level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FILE, AnnotationTarget.EXPRESSION}) @kotlin.annotation.Retention(value = AnnotationRetention.SOURCE) public final annotation class E4 : kotlin.Annotation {
|
@kotlin.RequiresOptIn(level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.PROPERTY_GETTER}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final annotation class E4 : kotlin.Annotation {
|
||||||
public constructor E4()
|
public constructor E4()
|
||||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@kotlin.RequiresOptIn(level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.PROPERTY_SETTER}) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final annotation class E5 : kotlin.Annotation {
|
||||||
|
public constructor E5()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user