Add some validation for Experimental/UseExperimental usages

#KT-22759 In Progress
This commit is contained in:
Alexander Udalov
2017-12-20 19:43:03 +01:00
parent 0bf0a315ed
commit 6d4e8f3781
18 changed files with 281 additions and 21 deletions
@@ -229,6 +229,12 @@ public interface Errors {
DiagnosticFactory2<PsiElement, FqName, Boolean> EXPERIMENTAL_API_USAGE = DiagnosticFactory2.create(WARNING);
DiagnosticFactory2<PsiElement, FqName, Boolean> EXPERIMENTAL_API_USAGE_ERROR = DiagnosticFactory2.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> USE_EXPERIMENTAL_WITHOUT_ARGUMENTS = DiagnosticFactory0.create(WARNING);
DiagnosticFactory1<KtAnnotationEntry, FqName> USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER = DiagnosticFactory1.create(WARNING);
DiagnosticFactory1<KtAnnotationEntry, FqName> USE_EXPERIMENTAL_ARGUMENT_HAS_NON_COMPILATION_IMPACT = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> EXPERIMENTAL_ANNOTATION_WITH_NO_IMPACT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET = DiagnosticFactory1.create(ERROR);
// Const
DiagnosticFactory0<PsiElement> CONST_VAL_NOT_TOP_LEVEL_OR_OBJECT = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<PsiElement> CONST_VAL_WITH_GETTER = DiagnosticFactory0.create(ERROR);
@@ -151,6 +151,13 @@ public class DefaultErrorMessages {
MAP.put(EXPERIMENTAL_API_USAGE, "This declaration is experimental and its usage should be marked with ''@{0}''{1}", TO_STRING, renderUseExperimental);
MAP.put(EXPERIMENTAL_API_USAGE_ERROR, "This declaration is experimental and its usage must be marked with ''@{0}''{1}", TO_STRING, renderUseExperimental);
MAP.put(USE_EXPERIMENTAL_WITHOUT_ARGUMENTS, "@UseExperimental without any arguments has no effect");
MAP.put(USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER, "Annotation ''{0}'' is not an experimental API marker, therefore its usage in @UseExperimental is ignored", TO_STRING);
MAP.put(USE_EXPERIMENTAL_ARGUMENT_HAS_NON_COMPILATION_IMPACT,
"Experimental annotation ''{0}'' has impact other than COMPILATION, therefore its usage in @UseExperimental is forbidden", TO_STRING);
MAP.put(EXPERIMENTAL_ANNOTATION_WITH_NO_IMPACT, "Experimental annotation with changesMayBreak = [] is not allowed");
MAP.put(EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET, "Experimental annotation cannot be used on the following code elements: {0}. Please remove these targets", STRING);
MAP.put(REDUNDANT_MODIFIER, "Modifier ''{0}'' is redundant because ''{1}'' is present", TO_STRING, TO_STRING);
MAP.put(REDUNDANT_OPEN_IN_INTERFACE, "Modifier 'open' is redundant for abstract interface members");
MAP.put(REDUNDANT_MODIFIER_IN_GETTER, "Visibility modifiers are redundant in getter");
@@ -28,6 +28,7 @@ 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.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.getAnnotationEntries
import org.jetbrains.kotlin.resolve.constants.ArrayValue
@@ -193,6 +194,8 @@ class AnnotationChecker(
}
companion object {
private val TARGET_ALLOWED_TARGETS = Name.identifier("allowedTargets")
private fun applicableTargetSet(entry: KtAnnotationEntry, trace: BindingTrace): Set<KotlinTarget> {
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: return KotlinTarget.DEFAULT_TARGET_SET
// For descriptor with error type, all targets are considered as possible
@@ -207,10 +210,12 @@ class AnnotationChecker(
}
fun applicableTargetSet(classDescriptor: ClassDescriptor): Set<KotlinTarget>? {
val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.target)
?: return null
val valueArguments = targetEntryDescriptor.allValueArguments
val valueArgument = valueArguments.entries.firstOrNull()?.value as? ArrayValue ?: return null
val targetEntryDescriptor = classDescriptor.annotations.findAnnotation(KotlinBuiltIns.FQ_NAMES.target) ?: return null
return loadAnnotationTargets(targetEntryDescriptor)
}
fun loadAnnotationTargets(targetEntryDescriptor: AnnotationDescriptor): Set<KotlinTarget>? {
val valueArgument = targetEntryDescriptor.allValueArguments[TARGET_ALLOWED_TARGETS] as? ArrayValue ?: return null
return valueArgument.value.filterIsInstance<EnumValue>().mapNotNull {
KotlinTarget.valueOrNull(it.enumEntryName.asString())
}.toSet()
@@ -98,7 +98,9 @@ private val DEFAULT_CLASSIFIER_USAGE_CHECKERS = listOf(
DeprecatedClassifierUsageChecker(), ApiVersionClassifierUsageChecker, MissingDependencyClassChecker.ClassifierUsage,
ExperimentalUsageChecker.ClassifierUsage
)
private val DEFAULT_ANNOTATION_CHECKERS = emptyList<AdditionalAnnotationChecker>()
private val DEFAULT_ANNOTATION_CHECKERS = listOf<AdditionalAnnotationChecker>(
ExperimentalMarkerDeclarationAnnotationChecker
)
abstract class PlatformConfigurator(
@@ -0,0 +1,91 @@
/*
* Copyright 2000-2018 JetBrains s.r.o. 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.checkers
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.diagnostics.Errors
import org.jetbrains.kotlin.psi.KtAnnotationEntry
import org.jetbrains.kotlin.resolve.AdditionalAnnotationChecker
import org.jetbrains.kotlin.resolve.AnnotationChecker
import org.jetbrains.kotlin.resolve.BindingContext
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.fqNameSafe
object ExperimentalMarkerDeclarationAnnotationChecker : AdditionalAnnotationChecker {
private val WRONG_TARGETS_FOR_MARKER = setOf(KotlinTarget.EXPRESSION, KotlinTarget.FILE)
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) {
var isAnnotatedWithExperimental = false
for (entry in entries) {
val annotation = trace.bindingContext.get(BindingContext.ANNOTATION, entry)
when (annotation?.fqName) {
ExperimentalUsageChecker.USE_EXPERIMENTAL_FQ_NAME -> {
val annotationClasses =
(annotation.allValueArguments[ExperimentalUsageChecker.USE_EXPERIMENTAL_ANNOTATION_CLASS] as? ArrayValue)?.value.orEmpty()
checkUseExperimentalUsage(annotationClasses, trace, entry)
}
ExperimentalUsageChecker.EXPERIMENTAL_FQ_NAME -> {
val impact = (annotation.allValueArguments[ExperimentalUsageChecker.IMPACT] as? ArrayValue)?.value
checkExperimentalUsage(impact, trace, entry)
isAnnotatedWithExperimental = true
}
}
}
if (isAnnotatedWithExperimental) {
checkMarkerTargets(entries, trace)
}
}
private fun checkUseExperimentalUsage(annotationClasses: List<ConstantValue<*>>, trace: BindingTrace, entry: KtAnnotationEntry) {
if (annotationClasses.isEmpty()) {
trace.report(Errors.USE_EXPERIMENTAL_WITHOUT_ARGUMENTS.on(entry))
return
}
for (annotationClass in annotationClasses) {
val classDescriptor =
(annotationClass as? KClassValue)?.value?.constructor?.declarationDescriptor as? ClassDescriptor
?: continue
val experimentality = with(ExperimentalUsageChecker) {
classDescriptor.loadExperimentalityForMarkerAnnotation()
}
if (experimentality == null) {
trace.report(Errors.USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER.on(entry, classDescriptor.fqNameSafe))
} else if (!experimentality.isCompilationOnly) {
trace.report(Errors.USE_EXPERIMENTAL_ARGUMENT_HAS_NON_COMPILATION_IMPACT.on(entry, experimentality.annotationFqName))
}
}
}
private fun checkExperimentalUsage(impact: List<ConstantValue<*>>?, trace: BindingTrace, entry: KtAnnotationEntry) {
if (impact != null && impact.isEmpty()) {
trace.report(Errors.EXPERIMENTAL_ANNOTATION_WITH_NO_IMPACT.on(entry))
}
}
private fun checkMarkerTargets(entries: List<KtAnnotationEntry>, trace: BindingTrace) {
val targetEntry =
entries.associate { entry -> entry to trace.bindingContext.get(BindingContext.ANNOTATION, entry) }
.entries
.firstOrNull { (_, descriptor) -> descriptor != null && descriptor.fqName == KotlinBuiltIns.FQ_NAMES.target }
?: return
val (entry, descriptor) = targetEntry
val allowedTargets = AnnotationChecker.loadAnnotationTargets(descriptor!!) ?: return
val wrongTargets = allowedTargets.intersect(WRONG_TARGETS_FOR_MARKER)
if (wrongTargets.isNotEmpty()) {
trace.report(
Errors.EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET.on(entry, wrongTargets.joinToString(transform = KotlinTarget::description))
)
}
}
}
@@ -41,20 +41,20 @@ import org.jetbrains.kotlin.utils.SmartSet
import org.jetbrains.kotlin.utils.addIfNotNull
object ExperimentalUsageChecker : CallChecker {
private val EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental")
private val USE_EXPERIMENTAL_FQ_NAME = FqName("kotlin.UseExperimental")
private val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
internal val EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental")
internal val USE_EXPERIMENTAL_FQ_NAME = FqName("kotlin.UseExperimental")
internal val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass")
private val LEVEL = Name.identifier("level")
private val WARNING_LEVEL = Name.identifier("WARNING")
private val ERROR_LEVEL = Name.identifier("ERROR")
private val IMPACT = Name.identifier("changesMayBreak")
internal val IMPACT = Name.identifier("changesMayBreak")
private val COMPILATION_IMPACT = Name.identifier("COMPILATION")
private val LINKAGE_IMPACT = Name.identifier("LINKAGE")
private val RUNTIME_IMPACT = Name.identifier("RUNTIME")
private data class Experimentality(val annotationFqName: FqName, val severity: Severity, val impact: List<Impact>) {
internal data class Experimentality(val annotationFqName: FqName, val severity: Severity, private val impact: List<Impact>) {
val isCompilationOnly: Boolean get() = impact.all(Impact.COMPILATION::equals)
enum class Severity { WARNING, ERROR }
@@ -72,7 +72,7 @@ object ExperimentalUsageChecker : CallChecker {
private fun checkExperimental(descriptor: DeclarationDescriptor, element: PsiElement, trace: BindingTrace) {
for (experimentality in descriptor.loadExperimentalities()) {
val (annotationFqName, severity, impact) = experimentality
val (annotationFqName, severity) = experimentality
val isBodyUsageOfCompilationExperimentality =
experimentality.isCompilationOnly && element.isBodyUsage()
@@ -95,22 +95,21 @@ object ExperimentalUsageChecker : CallChecker {
val result = SmartSet.create<Experimentality>()
for (annotation in annotations) {
result.addIfNotNull(annotation.loadExperimentalityForMarkerAnnotation())
result.addIfNotNull(annotation.annotationClass?.loadExperimentalityForMarkerAnnotation())
}
val container = containingDeclaration
if (container is ClassDescriptor && this !is ConstructorDescriptor) {
for (annotation in container.annotations) {
result.addIfNotNull(annotation.loadExperimentalityForMarkerAnnotation())
result.addIfNotNull(annotation.annotationClass?.loadExperimentalityForMarkerAnnotation())
}
}
return result
}
private fun AnnotationDescriptor.loadExperimentalityForMarkerAnnotation(): Experimentality? {
val experimental = annotationClass?.annotations?.findAnnotation(EXPERIMENTAL_FQ_NAME) ?: return null
val annotationFqName = fqName ?: return null
internal fun ClassDescriptor.loadExperimentalityForMarkerAnnotation(): Experimentality? {
val experimental = annotations.findAnnotation(EXPERIMENTAL_FQ_NAME) ?: return null
val severity = when ((experimental.allValueArguments[LEVEL] as? EnumValue)?.enumEntryName) {
WARNING_LEVEL -> Experimentality.Severity.WARNING
@@ -126,7 +125,7 @@ object ExperimentalUsageChecker : CallChecker {
}
} ?: Experimentality.DEFAULT_IMPACT
return Experimentality(annotationFqName, severity, impact)
return Experimentality(fqNameSafe, severity, impact)
}
// Returns true if this element appears in the body of some function and is not visible in any non-local declaration signature.
@@ -189,4 +188,5 @@ object ExperimentalUsageChecker : CallChecker {
checkExperimental(targetDescriptor, element, context.trace)
}
}
}
@@ -6,7 +6,7 @@ package api
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.COMPILATION])
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
AnnotationTarget.VALUE_PARAMETER)
annotation class ExperimentalAPI
@ExperimentalAPI
@@ -9,7 +9,7 @@ package api {
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@kotlin.Experimental(changesMayBreak = {Impact.COMPILATION}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION}) public final annotation class ExperimentalAPI : kotlin.Annotation {
@kotlin.Experimental(changesMayBreak = {Impact.COMPILATION}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS, AnnotationTarget.VALUE_PARAMETER}) public final annotation class ExperimentalAPI : kotlin.Annotation {
public constructor ExperimentalAPI()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -0,0 +1,4 @@
// !API_VERSION: 1.3
<!EXPERIMENTAL_ANNOTATION_WITH_NO_IMPACT!>@Experimental(Experimental.Level.WARNING, [])<!>
annotation class ExperimentalAPI
@@ -0,0 +1,8 @@
package
@kotlin.Experimental(changesMayBreak = {}, level = Level.WARNING) public final annotation class ExperimentalAPI : kotlin.Annotation {
public constructor ExperimentalAPI()
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
}
@@ -0,0 +1,23 @@
// !API_VERSION: 1.3
// FILE: api.kt
package api
import kotlin.annotation.AnnotationTarget.*
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.RUNTIME])
@Target(CLASS, ANNOTATION_CLASS, TYPE_PARAMETER, PROPERTY, FIELD, LOCAL_VARIABLE, VALUE_PARAMETER, CONSTRUCTOR, FUNCTION,
PROPERTY_GETTER, PROPERTY_SETTER, TYPE, TYPEALIAS)
annotation class E1
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.RUNTIME])
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(FILE)<!>
annotation class E2
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.RUNTIME])
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(EXPRESSION)<!>
annotation class E3
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.RUNTIME])
<!EXPERIMENTAL_ANNOTATION_WITH_WRONG_TARGET!>@Target(FILE, EXPRESSION)<!>
annotation class E4
@@ -0,0 +1,32 @@
package
package api {
@kotlin.Experimental(changesMayBreak = {Impact.RUNTIME}, 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}) public final annotation class E1 : kotlin.Annotation {
public constructor E1()
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
}
@kotlin.Experimental(changesMayBreak = {Impact.RUNTIME}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FILE}) public final annotation class E2 : kotlin.Annotation {
public constructor E2()
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
}
@kotlin.Experimental(changesMayBreak = {Impact.RUNTIME}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.EXPRESSION}) public final annotation class E3 : kotlin.Annotation {
public constructor E3()
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
}
@kotlin.Experimental(changesMayBreak = {Impact.RUNTIME}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.FILE, AnnotationTarget.EXPRESSION}) public final annotation class E4 : kotlin.Annotation {
public constructor E4()
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
}
}
@@ -0,0 +1,30 @@
// !API_VERSION: 1.3
// FILE: api.kt
package api
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.RUNTIME])
@Target(AnnotationTarget.PROPERTY)
annotation class BinaryExperimental
@BinaryExperimental
val x = ""
// FILE: usage.kt
import api.*
<!USE_EXPERIMENTAL_WITHOUT_ARGUMENTS!>@UseExperimental<!>
fun use1(): String {
return <!EXPERIMENTAL_API_USAGE!>x<!>
}
<!USE_EXPERIMENTAL_ARGUMENT_HAS_NON_COMPILATION_IMPACT!>@UseExperimental(BinaryExperimental::class)<!>
fun use2(): String {
return <!EXPERIMENTAL_API_USAGE!>x<!>
}
<!USE_EXPERIMENTAL_ARGUMENT_IS_NOT_MARKER!>@UseExperimental(UseExperimental::class)<!>
fun use3(): String {
return <!EXPERIMENTAL_API_USAGE!>x<!>
}
@@ -0,0 +1,16 @@
package
@kotlin.UseExperimental(annotationClass = {}) public fun use1(): kotlin.String
@kotlin.UseExperimental(annotationClass = {api.BinaryExperimental::class}) public fun use2(): kotlin.String
@kotlin.UseExperimental(annotationClass = {kotlin.UseExperimental::class}) public fun use3(): kotlin.String
package api {
@api.BinaryExperimental public val x: kotlin.String = ""
@kotlin.Experimental(changesMayBreak = {Impact.RUNTIME}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.PROPERTY}) public final annotation class BinaryExperimental : kotlin.Annotation {
public constructor BinaryExperimental()
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
}
}
@@ -6,7 +6,7 @@ package api
@Experimental(Experimental.Level.WARNING, [Experimental.Impact.COMPILATION])
@Target(AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS,
AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION)
AnnotationTarget.VALUE_PARAMETER)
annotation class ExperimentalAPI
@ExperimentalAPI
@@ -4,7 +4,7 @@ package api {
@api.ExperimentalAPI public val property: kotlin.String = ""
@api.ExperimentalAPI public fun function(): kotlin.String
@kotlin.Experimental(changesMayBreak = {Impact.COMPILATION}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS, AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION}) public final annotation class ExperimentalAPI : kotlin.Annotation {
@kotlin.Experimental(changesMayBreak = {Impact.COMPILATION}, level = Level.WARNING) @kotlin.annotation.Target(allowedTargets = {AnnotationTarget.TYPE, AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, AnnotationTarget.PROPERTY, AnnotationTarget.TYPEALIAS, AnnotationTarget.VALUE_PARAMETER}) public final annotation class ExperimentalAPI : kotlin.Annotation {
public constructor ExperimentalAPI()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -1833,6 +1833,24 @@ public class DiagnosticsTestWithStdLibGenerated extends AbstractDiagnosticsTestW
doTest(fileName);
}
@TestMetadata("experimentalWithNoImpact.kt")
public void testExperimentalWithNoImpact() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalWithNoImpact.kt");
doTest(fileName);
}
@TestMetadata("incorrectTargetsForExperimentalAnnotation.kt")
public void testIncorrectTargetsForExperimentalAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/incorrectTargetsForExperimentalAnnotation.kt");
doTest(fileName);
}
@TestMetadata("incorrectUseExperimental.kt")
public void testIncorrectUseExperimental() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/incorrectUseExperimental.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/topLevel.kt");
@@ -1833,6 +1833,24 @@ public class DiagnosticsTestWithStdLibUsingJavacGenerated extends AbstractDiagno
doTest(fileName);
}
@TestMetadata("experimentalWithNoImpact.kt")
public void testExperimentalWithNoImpact() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalWithNoImpact.kt");
doTest(fileName);
}
@TestMetadata("incorrectTargetsForExperimentalAnnotation.kt")
public void testIncorrectTargetsForExperimentalAnnotation() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/incorrectTargetsForExperimentalAnnotation.kt");
doTest(fileName);
}
@TestMetadata("incorrectUseExperimental.kt")
public void testIncorrectUseExperimental() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/incorrectUseExperimental.kt");
doTest(fileName);
}
@TestMetadata("topLevel.kt")
public void testTopLevel() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/testsWithStdLib/experimental/topLevel.kt");