From 69e06a242a7462c14a8e1604a2480aa80ba57f3f Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Tue, 21 Sep 2021 16:18:10 +0300 Subject: [PATCH] FE 1.0: spread OptIn markers to children except fake override case #KT-49001 Fixed --- .../checkers/ExperimentalUsageChecker.kt | 30 +++++-- .../experimental/classMembers.fir.kt | 89 ------------------- .../experimental/classMembers.kt | 9 +- .../experimental/deeplyNestedClass.kt | 4 +- .../experimental/implicitUsagesFuture.kt | 2 +- 5 files changed, 31 insertions(+), 103 deletions(-) delete mode 100644 compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.fir.kt diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt index 7bfe8f9bce3..0c29481751a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt @@ -169,18 +169,29 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { moduleAnnotationsResolver: ModuleAnnotationsResolver, languageVersionSettings: LanguageVersionSettings, visited: MutableSet = mutableSetOf(), - useFutureError: Boolean = false + useFutureError: Boolean = false, + useMarkersFromContainer: Boolean = true, ): Set { if (!visited.add(this)) return emptySet() val result = SmartSet.create() if (this is CallableMemberDescriptor && kind == CallableMemberDescriptor.Kind.FAKE_OVERRIDE) { for (overridden in overriddenDescriptors) { - result.addAll(overridden.loadExperimentalities( - moduleAnnotationsResolver, - languageVersionSettings, - visited, - useFutureError = !languageVersionSettings.supportsFeature(LanguageFeature.OptInContagiousSignatures) - )) + result.addAll( + overridden.loadExperimentalities( + moduleAnnotationsResolver, + languageVersionSettings, + visited, + useFutureError = !languageVersionSettings.supportsFeature(LanguageFeature.OptInContagiousSignatures), + useMarkersFromContainer = false + ) + ) + if (useMarkersFromContainer) { + (containingDeclaration as? ClassDescriptor)?.let { + result.addAll( + it.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visited, useFutureError) + ) + } + } } return result } @@ -220,6 +231,11 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { } } + val container = containingDeclaration + if (useMarkersFromContainer && container is ClassDescriptor && this !is ConstructorDescriptor) { + result.addAll(container.loadExperimentalities(moduleAnnotationsResolver, languageVersionSettings, visited, useFutureError)) + } + for (moduleAnnotationClassId in moduleAnnotationsResolver.getAnnotationsOnContainingModule(this)) { val annotationClass = module.findClassAcrossModuleDependencies(moduleAnnotationClassId) result.addIfNotNull(annotationClass?.loadExperimentalityForMarkerAnnotation()) diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.fir.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.fir.kt deleted file mode 100644 index 1bcbcbe5a6b..00000000000 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.fir.kt +++ /dev/null @@ -1,89 +0,0 @@ -// !OPT_IN: kotlin.RequiresOptIn -// FILE: api.kt - -package api - -@RequiresOptIn(level = RequiresOptIn.Level.WARNING) -@Target(AnnotationTarget.CLASS, AnnotationTarget.FUNCTION) -@Retention(AnnotationRetention.BINARY) -annotation class ExperimentalAPI - -@ExperimentalAPI -class C { - fun function(): String = "" - val property: String = "" - class Nested - inner class Inner -} - -@ExperimentalAPI -fun C.extension() {} - -// FILE: usage-propagate.kt - -package usage1 - -import api.* - -@ExperimentalAPI -fun useAll() { - val c: C = C() - c.function() - c.property - C.Nested() - c.Inner() - c.extension() -} - -@ExperimentalAPI -class Use { - fun useAll(c: C) { - c.function() - c.property - C.Nested() - c.Inner() - c.extension() - } -} - -// FILE: usage-use.kt - -package usage2 - -import api.* - -@OptIn(ExperimentalAPI::class) -fun useAll() { - val c: C = C() - c.function() - c.property - C.Nested() - c.Inner() - c.extension() -} - -@OptIn(ExperimentalAPI::class) -class Use { - fun useAll(c: C) { - c.function() - c.property - C.Nested() - c.Inner() - c.extension() - } -} - -// FILE: usage-none.kt - -package usage3 - -import api.* - -fun use() { - val c: C = C() - c.function() - c.property - C.Nested() - c.Inner() - c.extension() -} diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt index b378b5166df..4bce3c9aa8d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/classMembers.kt @@ -1,3 +1,4 @@ +// FIR_IDENTICAL // !OPT_IN: kotlin.RequiresOptIn // FILE: api.kt @@ -81,9 +82,9 @@ import api.* fun use() { val c: C = C() - c.function() - c.property - C.Nested() - c.Inner() + c.function() + c.property + C.Nested() + c.Inner() c.extension() } diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt index 73c0950078b..fca23c1262d 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/deeplyNestedClass.kt @@ -52,7 +52,7 @@ package usage3 import api.* fun use1() { - C.D.E.F() + C.D.E.F() } -fun use2(f: C.D.E.F) = f.hashCode() +fun use2(f: C.D.E.F) = f.hashCode() diff --git a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.kt b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.kt index d92d6f39d53..898d07818f0 100644 --- a/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.kt +++ b/compiler/testData/diagnostics/testsWithStdLib/experimental/implicitUsagesFuture.kt @@ -84,7 +84,7 @@ object O { operator fun provideDelegate(x: Any?, y: Any?): C = C() } -val x: String by O +val x: String by O @Marker class OperatorContainer : Comparable {