FE 1.0: spread OptIn markers to children except fake override case

#KT-49001 Fixed
This commit is contained in:
Mikhail Glukhikh
2021-09-21 16:18:10 +03:00
committed by TeamCityServer
parent 3045a5e920
commit 69e06a242a
5 changed files with 31 additions and 103 deletions
@@ -169,18 +169,29 @@ class ExperimentalUsageChecker(project: Project) : CallChecker {
moduleAnnotationsResolver: ModuleAnnotationsResolver,
languageVersionSettings: LanguageVersionSettings,
visited: MutableSet<DeclarationDescriptor> = mutableSetOf(),
useFutureError: Boolean = false
useFutureError: Boolean = false,
useMarkersFromContainer: Boolean = true,
): Set<Experimentality> {
if (!visited.add(this)) return emptySet()
val result = SmartSet.create<Experimentality>()
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())
@@ -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: <!OPT_IN_USAGE!>C<!> = <!OPT_IN_USAGE!>C<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>function<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>property<!>
<!OPT_IN_USAGE!>C<!>.<!OPT_IN_USAGE!>Nested<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>Inner<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>extension<!>()
}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
// !OPT_IN: kotlin.RequiresOptIn
// FILE: api.kt
@@ -81,9 +82,9 @@ import api.*
fun use() {
val c: <!OPT_IN_USAGE!>C<!> = <!OPT_IN_USAGE!>C<!>()
<!OPT_IN_USAGE!>c<!>.function()
<!OPT_IN_USAGE!>c<!>.property
<!OPT_IN_USAGE!>C<!>.Nested()
<!OPT_IN_USAGE!>c<!>.Inner()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>function<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>property<!>
<!OPT_IN_USAGE!>C<!>.<!OPT_IN_USAGE!>Nested<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>Inner<!>()
<!OPT_IN_USAGE!>c<!>.<!OPT_IN_USAGE!>extension<!>()
}
@@ -52,7 +52,7 @@ package usage3
import api.*
fun use1() {
<!OPT_IN_USAGE!>C<!>.D.E.F()
<!OPT_IN_USAGE!>C<!>.<!OPT_IN_USAGE!>D<!>.<!OPT_IN_USAGE!>E<!>.<!OPT_IN_USAGE!>F<!>()
}
fun use2(f: <!OPT_IN_USAGE!>C<!>.D.E.F) = f.hashCode()
fun use2(f: <!OPT_IN_USAGE!>C<!>.<!OPT_IN_USAGE!>D<!>.<!OPT_IN_USAGE!>E<!>.<!OPT_IN_USAGE!>F<!>) = <!OPT_IN_USAGE!>f<!>.<!OPT_IN_USAGE!>hashCode<!>()
@@ -84,7 +84,7 @@ object O {
operator fun provideDelegate(x: Any?, y: Any?): C = C()
}
val x: String by <!OPT_IN_USAGE_FUTURE_ERROR!>O<!>
val x: String by <!OPT_IN_USAGE_ERROR, OPT_IN_USAGE_FUTURE_ERROR!>O<!>
@Marker
class OperatorContainer : Comparable<OperatorContainer> {