Make EXPERIMENTAL_ANNOTATION_ON_OVERRIDE warning till 1.6

This commit is contained in:
Mikhail Glukhikh
2021-07-26 12:22:23 +03:00
parent bb38eaae61
commit 810def829c
18 changed files with 112 additions and 8 deletions
@@ -34867,6 +34867,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt");
} }
@Test
@TestMetadata("experimentalOnOverrideWarning.kt")
public void testExperimentalOnOverrideWarning() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalOnOverrideWarning.kt");
}
@Test @Test
@TestMetadata("experimentalSetter.kt") @TestMetadata("experimentalSetter.kt")
public void testExperimentalSetter() throws Exception { public void testExperimentalSetter() throws Exception {
@@ -34867,6 +34867,12 @@ public class FirOldFrontendDiagnosticsWithLightTreeTestGenerated extends Abstrac
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt");
} }
@Test
@TestMetadata("experimentalOnOverrideWarning.kt")
public void testExperimentalOnOverrideWarning() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalOnOverrideWarning.kt");
}
@Test @Test
@TestMetadata("experimentalSetter.kt") @TestMetadata("experimentalSetter.kt")
public void testExperimentalSetter() throws Exception { public void testExperimentalSetter() throws Exception {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve.jvm.checkers package org.jetbrains.kotlin.resolve.jvm.checkers
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtAnnotationEntry
@@ -16,7 +17,12 @@ import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
object ExplicitMetadataChecker : AdditionalAnnotationChecker { object ExplicitMetadataChecker : AdditionalAnnotationChecker {
private val METADATA_FQ_NAME = FqName("kotlin.Metadata") private val METADATA_FQ_NAME = FqName("kotlin.Metadata")
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) { override fun checkEntries(
entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings
) {
for (entry in entries) { for (entry in entries) {
val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue val descriptor = trace.get(BindingContext.ANNOTATION, entry) ?: continue
if (descriptor.fqName == METADATA_FQ_NAME) { if (descriptor.fqName == METADATA_FQ_NAME) {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve.jvm.checkers package org.jetbrains.kotlin.resolve.jvm.checkers
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention import org.jetbrains.kotlin.descriptors.annotations.KotlinRetention
@@ -36,7 +37,12 @@ object FileClassAnnotationsChecker : AdditionalAnnotationChecker {
// JvmName & JvmMultifileClass annotations are applicable to multi-file class parts regardless of their retention. // 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) private val alwaysApplicable = hashSetOf(JvmFileClassUtil.JVM_NAME, JvmFileClassUtil.JVM_MULTIFILE_CLASS)
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) { override fun checkEntries(
entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings
) {
val fileAnnotationsToCheck = arrayListOf<Pair<KtAnnotationEntry, ClassDescriptor>>() val fileAnnotationsToCheck = arrayListOf<Pair<KtAnnotationEntry, ClassDescriptor>>()
for (entry in entries) { for (entry in entries) {
if (entry.useSiteTarget?.getAnnotationUseSiteTarget() != AnnotationUseSiteTarget.FILE) continue if (entry.useSiteTarget?.getAnnotationUseSiteTarget() != AnnotationUseSiteTarget.FILE) continue
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.resolve.jvm.checkers package org.jetbrains.kotlin.resolve.jvm.checkers
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget 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
@@ -19,7 +20,12 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.isRepeatableAnnotation
import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm import org.jetbrains.kotlin.resolve.jvm.diagnostics.ErrorsJvm
object RepeatableAnnotationChecker : AdditionalAnnotationChecker { object RepeatableAnnotationChecker : AdditionalAnnotationChecker {
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) { override fun checkEntries(
entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings
) {
val entryTypesWithAnnotations = hashMapOf<FqName, MutableList<AnnotationUseSiteTarget?>>() val entryTypesWithAnnotations = hashMapOf<FqName, MutableList<AnnotationUseSiteTarget?>>()
for (entry in entries) { for (entry in entries) {
@@ -292,6 +292,7 @@ public interface Errors {
DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_ON_WRONG_TARGET = DiagnosticFactory1.create(ERROR); DiagnosticFactory1<KtAnnotationEntry, String> EXPERIMENTAL_ANNOTATION_ON_WRONG_TARGET = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> EXPERIMENTAL_ANNOTATION_ON_OVERRIDE = DiagnosticFactory0.create(ERROR); DiagnosticFactory0<KtAnnotationEntry> EXPERIMENTAL_ANNOTATION_ON_OVERRIDE = DiagnosticFactory0.create(ERROR);
DiagnosticFactory0<KtAnnotationEntry> EXPERIMENTAL_ANNOTATION_ON_OVERRIDE_WARNING = DiagnosticFactory0.create(WARNING);
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);
@@ -174,6 +174,7 @@ public class DefaultErrorMessages {
MAP.put(EXPERIMENTAL_ANNOTATION_ON_WRONG_TARGET, "Opt-in requirement marker annotation cannot be used on {0}", STRING); MAP.put(EXPERIMENTAL_ANNOTATION_ON_WRONG_TARGET, "Opt-in requirement marker annotation cannot be used on {0}", STRING);
MAP.put(EXPERIMENTAL_ANNOTATION_ON_OVERRIDE, "Opt-in requirement marker annotation on override requires the same marker on base declaration"); MAP.put(EXPERIMENTAL_ANNOTATION_ON_OVERRIDE, "Opt-in requirement marker annotation on override requires the same marker on base declaration");
MAP.put(EXPERIMENTAL_ANNOTATION_ON_OVERRIDE_WARNING, "Opt-in requirement marker annotation on override requires the same marker on base declaration (will be an error in 1.6)");
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);
@@ -230,7 +230,7 @@ class AnnotationChecker(
} }
for (checker in additionalCheckers) { for (checker in additionalCheckers) {
checker.checkEntries(entries, actualTargets.defaultTargets, trace) checker.checkEntries(entries, actualTargets.defaultTargets, trace, languageVersionSettings)
} }
} }
@@ -381,5 +381,10 @@ private typealias TargetLists = AnnotationTargetLists
private typealias TargetList = AnnotationTargetList private typealias TargetList = AnnotationTargetList
interface AdditionalAnnotationChecker { interface AdditionalAnnotationChecker {
fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) fun checkEntries(
entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings
)
} }
@@ -6,6 +6,8 @@
package org.jetbrains.kotlin.resolve.checkers package org.jetbrains.kotlin.resolve.checkers
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
@@ -37,7 +39,8 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
override fun checkEntries( override fun checkEntries(
entries: List<KtAnnotationEntry>, entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>, actualTargets: List<KotlinTarget>,
trace: BindingTrace trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings
) { ) {
var isAnnotatedWithExperimental = false var isAnnotatedWithExperimental = false
@@ -88,7 +91,11 @@ class ExperimentalMarkerDeclarationAnnotationChecker(private val module: ModuleD
if (descriptor is CallableMemberDescriptor && if (descriptor is CallableMemberDescriptor &&
!descriptor.hasExperimentalOverriddenDescriptors(annotationClass.fqNameSafe) !descriptor.hasExperimentalOverriddenDescriptors(annotationClass.fqNameSafe)
) { ) {
trace.report(Errors.EXPERIMENTAL_ANNOTATION_ON_OVERRIDE.on(entry)) if (languageVersionSettings.supportsFeature(LanguageFeature.OptInOnOverrideForbidden)) {
trace.report(Errors.EXPERIMENTAL_ANNOTATION_ON_OVERRIDE.on(entry))
} else {
trace.report(Errors.EXPERIMENTAL_ANNOTATION_ON_OVERRIDE_WARNING.on(entry))
}
} }
} }
} }
@@ -0,0 +1,12 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !LANGUAGE: -OptInOnOverrideForbidden
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
@Retention(AnnotationRetention.BINARY)
annotation class E
class My {
@E
override fun hashCode() = 0
}
@@ -0,0 +1,12 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !LANGUAGE: -OptInOnOverrideForbidden
@RequiresOptIn(level = RequiresOptIn.Level.WARNING)
@Retention(AnnotationRetention.BINARY)
annotation class E
class My {
<!EXPERIMENTAL_ANNOTATION_ON_OVERRIDE_WARNING!>@E<!>
override fun hashCode() = 0
}
@@ -0,0 +1,15 @@
package
@kotlin.RequiresOptIn(level = Level.WARNING) @kotlin.annotation.Retention(value = AnnotationRetention.BINARY) public final annotation class E : kotlin.Annotation {
public constructor E()
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
}
public final class My {
public constructor My()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
@E public open override /*1*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
}
@@ -1,4 +1,5 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !LANGUAGE: +OptInOnOverrideForbidden
// FILE: api.kt // FILE: api.kt
package api package api
@@ -1,4 +1,5 @@
// !USE_EXPERIMENTAL: kotlin.RequiresOptIn // !USE_EXPERIMENTAL: kotlin.RequiresOptIn
// !LANGUAGE: +OptInOnOverrideForbidden
// FILE: api.kt // FILE: api.kt
package api package api
@@ -34963,6 +34963,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt");
} }
@Test
@TestMetadata("experimentalOnOverrideWarning.kt")
public void testExperimentalOnOverrideWarning() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalOnOverrideWarning.kt");
}
@Test @Test
@TestMetadata("experimentalSetter.kt") @TestMetadata("experimentalSetter.kt")
public void testExperimentalSetter() throws Exception { public void testExperimentalSetter() throws Exception {
@@ -216,6 +216,7 @@ enum class LanguageFeature(
TypeInferenceOnCallsWithSelfTypes(KOTLIN_1_6), TypeInferenceOnCallsWithSelfTypes(KOTLIN_1_6),
WarnAboutNonExhaustiveWhenOnAlgebraicTypes(KOTLIN_1_6, kind = BUG_FIX), WarnAboutNonExhaustiveWhenOnAlgebraicTypes(KOTLIN_1_6, kind = BUG_FIX),
InstantiationOfAnnotationClasses(KOTLIN_1_6), InstantiationOfAnnotationClasses(KOTLIN_1_6),
OptInOnOverrideForbidden(KOTLIN_1_6, kind = BUG_FIX),
// 1.7 // 1.7
@@ -34867,6 +34867,12 @@ public class DiagnosisCompilerTestFE10TestdataTestGenerated extends AbstractDiag
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt"); runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalIsNotEnabled.kt");
} }
@Test
@TestMetadata("experimentalOnOverrideWarning.kt")
public void testExperimentalOnOverrideWarning() throws Exception {
runTest("compiler/testData/diagnostics/testsWithStdLib/experimental/experimentalOnOverrideWarning.kt");
}
@Test @Test
@TestMetadata("experimentalSetter.kt") @TestMetadata("experimentalSetter.kt")
public void testExperimentalSetter() throws Exception { public void testExperimentalSetter() throws Exception {
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.js.resolve.diagnostics package org.jetbrains.kotlin.js.resolve.diagnostics
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget import org.jetbrains.kotlin.descriptors.annotations.KotlinTarget
import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils import org.jetbrains.kotlin.js.translate.utils.AnnotationsUtils
import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtAnnotationEntry
@@ -24,7 +25,12 @@ import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingTrace import org.jetbrains.kotlin.resolve.BindingTrace
object JsQualifierChecker : AdditionalAnnotationChecker { object JsQualifierChecker : AdditionalAnnotationChecker {
override fun checkEntries(entries: List<KtAnnotationEntry>, actualTargets: List<KotlinTarget>, trace: BindingTrace) { override fun checkEntries(
entries: List<KtAnnotationEntry>,
actualTargets: List<KotlinTarget>,
trace: BindingTrace,
languageVersionSettings: LanguageVersionSettings
) {
val bindingContext = trace.bindingContext val bindingContext = trace.bindingContext
for (entry in entries) { for (entry in entries) {
val annotation = bindingContext[BindingContext.ANNOTATION, entry] ?: continue val annotation = bindingContext[BindingContext.ANNOTATION, entry] ?: continue