Support custom message in RequiresOptIn
#KT-34648 Fixed
This commit is contained in:
@@ -255,11 +255,11 @@ public interface Errors {
|
||||
DiagnosticFactory1<PsiElement, FqName> ILLEGAL_KOTLIN_VERSION_STRING_VALUE = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> NEWER_VERSION_IN_SINCE_KOTLIN = DiagnosticFactory1.create(WARNING);
|
||||
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_API_USAGE = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_API_USAGE = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory2<PsiElement, FqName, DeclarationDescriptor> EXPERIMENTAL_OVERRIDE = DiagnosticFactory2.create(WARNING);
|
||||
DiagnosticFactory2<PsiElement, FqName, DeclarationDescriptor> EXPERIMENTAL_OVERRIDE_ERROR = DiagnosticFactory2.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_OVERRIDE = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_OVERRIDE_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> EXPERIMENTAL_IS_NOT_ENABLED = DiagnosticFactory0.create(WARNING);
|
||||
DiagnosticFactory0<PsiElement> EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION = DiagnosticFactory0.create(ERROR);
|
||||
@@ -270,8 +270,8 @@ public interface Errors {
|
||||
DiagnosticFactory1<KtAnnotationEntry, FqName> USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_UNSIGNED_LITERALS = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, FqName> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS = DiagnosticFactory1.create(WARNING);
|
||||
DiagnosticFactory1<PsiElement, String> EXPERIMENTAL_UNSIGNED_LITERALS_ERROR = DiagnosticFactory1.create(ERROR);
|
||||
|
||||
DiagnosticFactory0<PsiElement> NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES = DiagnosticFactory0.create(ERROR);
|
||||
|
||||
|
||||
+6
-6
@@ -147,11 +147,11 @@ public class DefaultErrorMessages {
|
||||
MAP.put(ILLEGAL_KOTLIN_VERSION_STRING_VALUE, "Invalid @{0} annotation value (should be ''major.minor'' or ''major.minor.patch'')", TO_STRING);
|
||||
MAP.put(NEWER_VERSION_IN_SINCE_KOTLIN, "The version is greater than the specified API version {0}", STRING);
|
||||
|
||||
MAP.put(EXPERIMENTAL_API_USAGE, "This declaration is experimental and its usage should be marked with ''@{0}'' or ''@OptIn({0}::class)''", TO_STRING);
|
||||
MAP.put(EXPERIMENTAL_API_USAGE_ERROR, "This declaration is experimental and its usage must be marked with ''@{0}'' or ''@OptIn({0}::class)''", TO_STRING);
|
||||
MAP.put(EXPERIMENTAL_API_USAGE, "{0}", STRING);
|
||||
MAP.put(EXPERIMENTAL_API_USAGE_ERROR, "{0}", STRING);
|
||||
|
||||
MAP.put(EXPERIMENTAL_OVERRIDE, "This declaration overrides experimental member of supertype ''{1}'' and should be annotated with ''@{0}''", TO_STRING, NAME);
|
||||
MAP.put(EXPERIMENTAL_OVERRIDE_ERROR, "This declaration overrides experimental member of supertype ''{1}'' and must be annotated with ''@{0}''", TO_STRING, NAME);
|
||||
MAP.put(EXPERIMENTAL_OVERRIDE, "{0}", STRING);
|
||||
MAP.put(EXPERIMENTAL_OVERRIDE_ERROR, "{0}", STRING);
|
||||
|
||||
MAP.put(EXPERIMENTAL_IS_NOT_ENABLED, "This class can only be used with the compiler argument '-Xopt-in=kotlin.RequiresOptIn'");
|
||||
MAP.put(EXPERIMENTAL_CAN_ONLY_BE_USED_AS_ANNOTATION, "This class can only be used as an annotation");
|
||||
@@ -161,8 +161,8 @@ public class DefaultErrorMessages {
|
||||
MAP.put(USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER, "Annotation ''{0}'' is not an opt-in requirement marker, therefore its usage in @OptIn is ignored", TO_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_UNSIGNED_LITERALS, "Unsigned literals are experimental and their usages should be marked with ''@{0}'' or ''@OptIn({0}::class)''", TO_STRING);
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "Unsigned literals are experimental and their usages must be marked with ''@{0}'' or ''@OptIn({0}::class)''", TO_STRING);
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS, "{0}", STRING);
|
||||
MAP.put(EXPERIMENTAL_UNSIGNED_LITERALS_ERROR, "{0}", STRING);
|
||||
|
||||
MAP.put(NON_PARENTHESIZED_ANNOTATIONS_ON_FUNCTIONAL_TYPES, "Non-parenthesized annotations on function types without receiver aren't yet supported (see KT-31734 for details)");
|
||||
|
||||
|
||||
+41
-15
@@ -37,6 +37,7 @@ import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.constants.ArrayValue
|
||||
import org.jetbrains.kotlin.resolve.constants.EnumValue
|
||||
import org.jetbrains.kotlin.resolve.constants.KClassValue
|
||||
import org.jetbrains.kotlin.resolve.constants.StringValue
|
||||
import org.jetbrains.kotlin.resolve.deprecation.CoroutineCompatibilitySupport
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationLevelValue
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DeprecationResolver
|
||||
@@ -51,7 +52,7 @@ import org.jetbrains.kotlin.utils.addIfNotNull
|
||||
class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
private val moduleAnnotationsResolver = ModuleAnnotationsResolver.getInstance(project)
|
||||
|
||||
data class Experimentality(val annotationFqName: FqName, val severity: Severity) {
|
||||
data class Experimentality(val annotationFqName: FqName, val severity: Severity, val message: String?) {
|
||||
enum class Severity { WARNING, ERROR }
|
||||
|
||||
companion object {
|
||||
@@ -59,9 +60,14 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
}
|
||||
}
|
||||
|
||||
class ExperimentalityDiagnostic(
|
||||
val factory: DiagnosticFactory1<PsiElement, String>,
|
||||
val defaultMessage: (FqName) -> String
|
||||
)
|
||||
|
||||
data class ExperimentalityDiagnostics(
|
||||
val warning: DiagnosticFactory1<PsiElement, FqName>,
|
||||
val error: DiagnosticFactory1<PsiElement, FqName>
|
||||
val warning: ExperimentalityDiagnostic,
|
||||
val error: ExperimentalityDiagnostic
|
||||
)
|
||||
|
||||
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
|
||||
@@ -84,18 +90,30 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
internal val WAS_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
|
||||
|
||||
private val LEVEL = Name.identifier("level")
|
||||
private val MESSAGE = Name.identifier("message")
|
||||
private val WARNING_LEVEL = Name.identifier("WARNING")
|
||||
private val ERROR_LEVEL = Name.identifier("ERROR")
|
||||
|
||||
private val EXPERIMENTAL_API_DIAGNOSTICS = ExperimentalityDiagnostics(
|
||||
Errors.EXPERIMENTAL_API_USAGE, Errors.EXPERIMENTAL_API_USAGE_ERROR
|
||||
internal fun getDefaultDiagnosticMessage(prefix: String) = fun(fqName: FqName): String {
|
||||
return "$prefix with '@${fqName.asString()}' or '@OptIn(${fqName.asString()}::class)'"
|
||||
}
|
||||
|
||||
private val USAGE_DIAGNOSTICS = ExperimentalityDiagnostics(
|
||||
warning = ExperimentalityDiagnostic(
|
||||
Errors.EXPERIMENTAL_API_USAGE,
|
||||
getDefaultDiagnosticMessage("This declaration is experimental and its usage should be marked")
|
||||
),
|
||||
error = ExperimentalityDiagnostic(
|
||||
Errors.EXPERIMENTAL_API_USAGE_ERROR,
|
||||
getDefaultDiagnosticMessage("This declaration is experimental and its usage must be marked")
|
||||
)
|
||||
)
|
||||
|
||||
fun reportNotAcceptedExperimentalities(
|
||||
experimentalities: Collection<Experimentality>, element: PsiElement, context: CheckerContext
|
||||
) {
|
||||
reportNotAcceptedExperimentalities(
|
||||
experimentalities, element, context.languageVersionSettings, context.trace, EXPERIMENTAL_API_DIAGNOSTICS
|
||||
experimentalities, element, context.languageVersionSettings, context.trace, USAGE_DIAGNOSTICS
|
||||
)
|
||||
}
|
||||
|
||||
@@ -106,13 +124,13 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
trace: BindingTrace,
|
||||
diagnostics: ExperimentalityDiagnostics
|
||||
) {
|
||||
for ((annotationFqName, severity) in experimentalities) {
|
||||
for ((annotationFqName, severity, message) in experimentalities) {
|
||||
if (!element.isExperimentalityAccepted(annotationFqName, languageVersionSettings, trace.bindingContext)) {
|
||||
val diagnostic = when (severity) {
|
||||
Experimentality.Severity.WARNING -> diagnostics.warning
|
||||
Experimentality.Severity.ERROR -> diagnostics.error
|
||||
}
|
||||
trace.reportDiagnosticOnce(diagnostic.on(element, annotationFqName))
|
||||
trace.reportDiagnosticOnce(diagnostic.factory.on(element, message ?: diagnostic.defaultMessage(annotationFqName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -153,13 +171,16 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
?: annotations.findAnnotation(OLD_EXPERIMENTAL_FQ_NAME)
|
||||
?: return null
|
||||
|
||||
val severity = when ((experimental.allValueArguments[LEVEL] as? EnumValue)?.enumEntryName) {
|
||||
val arguments = experimental.allValueArguments
|
||||
val severity = when ((arguments[LEVEL] as? EnumValue)?.enumEntryName) {
|
||||
WARNING_LEVEL -> Experimentality.Severity.WARNING
|
||||
ERROR_LEVEL -> Experimentality.Severity.ERROR
|
||||
else -> Experimentality.DEFAULT_SEVERITY
|
||||
}
|
||||
|
||||
return Experimentality(fqNameSafe, severity)
|
||||
val message = (arguments[MESSAGE] as? StringValue)?.value
|
||||
|
||||
return Experimentality(fqNameSafe, severity, message)
|
||||
}
|
||||
|
||||
private fun PsiElement.isExperimentalityAccepted(annotationFqName: FqName, context: CheckerContext): Boolean =
|
||||
@@ -344,12 +365,17 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
|
||||
|
||||
for ((experimentality, member) in experimentalOverridden) {
|
||||
if (!declaration.isExperimentalityAccepted(experimentality.annotationFqName, context)) {
|
||||
val diagnostic = when (experimentality.severity) {
|
||||
Experimentality.Severity.WARNING -> Errors.EXPERIMENTAL_OVERRIDE
|
||||
Experimentality.Severity.ERROR -> Errors.EXPERIMENTAL_OVERRIDE_ERROR
|
||||
}
|
||||
val reportOn = (declaration as? KtNamedDeclaration)?.nameIdentifier ?: declaration
|
||||
context.trace.report(diagnostic.on(reportOn, experimentality.annotationFqName, member.containingDeclaration))
|
||||
|
||||
val (diagnostic, defaultMessageVerb) = when (experimentality.severity) {
|
||||
Experimentality.Severity.WARNING -> Errors.EXPERIMENTAL_OVERRIDE to "should"
|
||||
Experimentality.Severity.ERROR -> Errors.EXPERIMENTAL_OVERRIDE_ERROR to "must"
|
||||
}
|
||||
val message = experimentality.message
|
||||
?: "This declaration overrides experimental member of supertype " +
|
||||
"'${member.containingDeclaration.name.asString()}' and $defaultMessageVerb be annotated " +
|
||||
"with '@${experimentality.annotationFqName.asString()}'"
|
||||
context.trace.report(diagnostic.on(reportOn, message))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+8
-1
@@ -319,7 +319,14 @@ class ConstantExpressionEvaluator(
|
||||
|
||||
companion object {
|
||||
private val EXPERIMENTAL_UNSIGNED_LITERALS_DIAGNOSTICS = ExperimentalUsageChecker.ExperimentalityDiagnostics(
|
||||
Errors.EXPERIMENTAL_UNSIGNED_LITERALS, Errors.EXPERIMENTAL_UNSIGNED_LITERALS_ERROR
|
||||
warning = ExperimentalUsageChecker.ExperimentalityDiagnostic(
|
||||
Errors.EXPERIMENTAL_UNSIGNED_LITERALS,
|
||||
ExperimentalUsageChecker.getDefaultDiagnosticMessage("Unsigned literals are experimental and their usages should be marked")
|
||||
),
|
||||
error = ExperimentalUsageChecker.ExperimentalityDiagnostic(
|
||||
Errors.EXPERIMENTAL_UNSIGNED_LITERALS_ERROR,
|
||||
ExperimentalUsageChecker.getDefaultDiagnosticMessage("Unsigned literals are experimental and their usages must be marked")
|
||||
)
|
||||
)
|
||||
|
||||
@JvmStatic
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS,
|
||||
AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS,
|
||||
AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
interface I
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
interface I
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class API
|
||||
|
||||
@API
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class API
|
||||
|
||||
@API
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
Vendored
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.PROPERTY, AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
+1
-1
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
|
||||
+4
-4
@@ -5,21 +5,21 @@ package api
|
||||
|
||||
import kotlin.annotation.AnnotationTarget.*
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
|
||||
PROPERTY_GETTER, PROPERTY_SETTER, TYPE, TYPEALIAS)
|
||||
annotation class E1
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(FILE)
|
||||
annotation class E2
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class E3
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(FILE, EXPRESSION)
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class E4
|
||||
|
||||
+4
-4
@@ -5,21 +5,21 @@ package api
|
||||
|
||||
import kotlin.annotation.AnnotationTarget.*
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
|
||||
PROPERTY_GETTER, PROPERTY_SETTER, TYPE, TYPEALIAS)
|
||||
annotation class E1
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(FILE)<!>
|
||||
annotation class E2
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(EXPRESSION)<!>
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class E3
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(FILE, EXPRESSION)<!>
|
||||
@Retention(AnnotationRetention.SOURCE)
|
||||
annotation class E4
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class E
|
||||
|
||||
open class Base {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class E
|
||||
|
||||
open class Base {
|
||||
|
||||
compiler/testData/diagnostics/testsWithStdLib/experimental/overrideDifferentExperimentalities.fir.kt
Vendored
+2
-2
@@ -1,8 +1,8 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class E1
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class E3
|
||||
|
||||
interface Base1 {
|
||||
|
||||
Vendored
+2
-2
@@ -1,8 +1,8 @@
|
||||
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class E1
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class E3
|
||||
|
||||
interface Base1 {
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS,
|
||||
AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS,
|
||||
AnnotationTarget.VALUE_PARAMETER)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import kotlin.RequiresOptIn
|
||||
|
||||
// Usages with FQ names should be OK
|
||||
|
||||
@kotlin.RequiresOptIn(kotlin.RequiresOptIn.Level.ERROR)
|
||||
@kotlin.RequiresOptIn(level = kotlin.RequiresOptIn.Level.ERROR)
|
||||
annotation class M
|
||||
|
||||
|
||||
|
||||
+1
-1
@@ -14,7 +14,7 @@ import kotlin.RequiresOptIn
|
||||
|
||||
// Usages with FQ names should be OK
|
||||
|
||||
@kotlin.RequiresOptIn(kotlin.RequiresOptIn.Level.ERROR)
|
||||
@kotlin.RequiresOptIn(level = kotlin.RequiresOptIn.Level.ERROR)
|
||||
annotation class M
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI1
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI2
|
||||
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI1
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class ExperimentalAPI2
|
||||
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class VeryExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
|
||||
+2
-2
@@ -3,11 +3,11 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
annotation class VeryExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
|
||||
Vendored
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.ERROR)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.ERROR)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
annotation class ExperimentalAPI
|
||||
|
||||
@ExperimentalAPI
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class E
|
||||
|
||||
|
||||
+1
-1
@@ -4,7 +4,7 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.CLASS)
|
||||
annotation class E
|
||||
|
||||
|
||||
+3
-3
@@ -3,15 +3,15 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class E1
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class E2
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class E3
|
||||
|
||||
|
||||
Vendored
+3
-3
@@ -3,15 +3,15 @@
|
||||
|
||||
package api
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class E1
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class E2
|
||||
|
||||
@RequiresOptIn(RequiresOptIn.Level.WARNING)
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
|
||||
@Target(AnnotationTarget.FUNCTION)
|
||||
annotation class E3
|
||||
|
||||
|
||||
@@ -15,16 +15,24 @@ import kotlin.reflect.KClass
|
||||
/**
|
||||
* Signals that the annotated annotation class is a marker of an API that requires an explicit opt-in.
|
||||
*
|
||||
* Call sites of any declaration annotated with that marker should opt-in to the API either by using [OptIn],
|
||||
* Call sites of any declaration annotated with that marker should opt in to the API either by using [OptIn],
|
||||
* or by being annotated with that marker themselves, effectively causing further propagation of the opt-in requirement.
|
||||
*
|
||||
* This class requires opt-in itself and can only be used with the compiler argument `-Xopt-in=kotlin.RequiresOptIn`.
|
||||
*
|
||||
* @property message message to be reported on usages of API without an explicit opt-in, or empty string for the default message.
|
||||
* The default message is: "This declaration is experimental and its usage should be marked with 'Marker'
|
||||
* or '@OptIn(Marker::class)'", where `Marker` is the opt-in requirement marker.
|
||||
* @property level specifies how usages of API without an explicit opt-in are reported in code.
|
||||
*/
|
||||
@Target(ANNOTATION_CLASS)
|
||||
@Retention(BINARY)
|
||||
@SinceKotlin("1.3")
|
||||
@RequireKotlin("1.3.70", versionKind = RequireKotlinVersionKind.COMPILER_VERSION)
|
||||
public annotation class RequiresOptIn(val level: Level = Level.ERROR) {
|
||||
public annotation class RequiresOptIn(
|
||||
val message: String = "",
|
||||
val level: Level = Level.ERROR
|
||||
) {
|
||||
/**
|
||||
* Severity of the diagnostic that should be reported on usages which did not explicitly opted into
|
||||
* the API either by using [OptIn] or by being annotated with the corresponding marker annotation.
|
||||
@@ -40,7 +48,7 @@ public annotation class RequiresOptIn(val level: Level = Level.ERROR) {
|
||||
|
||||
/**
|
||||
* Allows to use the API denoted by the given markers in the annotated file, declaration, or expression.
|
||||
* If a declaration is annotated with [OptIn], its usages are **not** required to opt-in to that API.
|
||||
* If a declaration is annotated with [OptIn], its usages are **not** required to opt in to that API.
|
||||
*
|
||||
* This class requires opt-in itself and can only be used with the compiler argument `-Xopt-in=kotlin.RequiresOptIn`.
|
||||
*/
|
||||
|
||||
+1
@@ -160,6 +160,7 @@ public abstract interface annotation class kotlin/ReplaceWith : java/lang/annota
|
||||
|
||||
public abstract interface annotation class kotlin/RequiresOptIn : java/lang/annotation/Annotation {
|
||||
public abstract fun level ()Lkotlin/RequiresOptIn$Level;
|
||||
public abstract fun message ()Ljava/lang/String;
|
||||
}
|
||||
|
||||
public final class kotlin/RequiresOptIn$Level : java/lang/Enum {
|
||||
|
||||
Reference in New Issue
Block a user