K1: Force propagating deprecation on NOT_CONSIDERED JDK members to overrides

^KT-60858 Related
KT-60659 In Progress
^KT-60769 In Progress
This commit is contained in:
Denis.Zharkov
2023-07-28 19:59:25 +02:00
committed by Space Team
parent 1e86a82ee1
commit eae97e4f76
9 changed files with 74 additions and 22 deletions
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.TypeAliasDescriptor
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.descriptors.annotations.BuiltInAnnotationDescriptor
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.annotations.argumentValue
@@ -23,8 +24,16 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
internal sealed class DeprecatedByAnnotation(
val annotation: AnnotationDescriptor,
override val target: DeclarationDescriptor,
override val propagatesToOverrides: Boolean
final override val propagatesToOverrides: Boolean,
final override val forcePropagationToOverrides: Boolean = false,
) : DescriptorBasedDeprecationInfo() {
init {
require(!forcePropagationToOverrides || propagatesToOverrides) {
"if something is `forcePropagationToOverrides`, it's expected that `propagatesToOverrides` == true, too"
}
}
override val message: String?
get() = (annotation.argumentValue("message") as? StringValue)?.value
@@ -37,8 +46,9 @@ internal sealed class DeprecatedByAnnotation(
class StandardDeprecated(
annotation: AnnotationDescriptor,
target: DeclarationDescriptor,
propagatesToOverrides: Boolean
) : DeprecatedByAnnotation(annotation, target, propagatesToOverrides) {
propagatesToOverrides: Boolean,
forcePropagationToOverrides: Boolean = false,
) : DeprecatedByAnnotation(annotation, target, propagatesToOverrides, forcePropagationToOverrides) {
override val deprecationLevel: DeprecationLevelValue
get() = when ((annotation.argumentValue("level") as? EnumValue)?.enumEntryName?.asString()) {
"WARNING" -> WARNING
@@ -105,7 +115,14 @@ internal sealed class DeprecatedByAnnotation(
val level = computeLevelForDeprecatedSinceKotlin(deprecatedSinceKotlinAnnotation, apiVersion) ?: return null
return DeprecatedSince(deprecatedAnnotation, target, propagatesToOverrides, level)
}
return StandardDeprecated(deprecatedAnnotation, target, propagatesToOverrides)
val forcePropagationToOverrides =
(deprecatedAnnotation as? BuiltInAnnotationDescriptor)?.forcePropagationDeprecationToOverrides == true
return StandardDeprecated(
deprecatedAnnotation,
target,
propagatesToOverrides || forcePropagationToOverrides,
forcePropagationToOverrides = forcePropagationToOverrides
)
}
}
}
@@ -116,6 +133,8 @@ internal data class DeprecatedByOverridden(private val deprecations: Collection<
assert(deprecations.none { it is DeprecatedByOverridden })
}
override val forcePropagationToOverrides: Boolean = deprecations.any { it.forcePropagationToOverrides }
override val deprecationLevel: DeprecationLevelValue = deprecations.map(DescriptorBasedDeprecationInfo::deprecationLevel).minOrNull()!!
override val target: DeclarationDescriptor
@@ -46,7 +46,11 @@ class DeprecationResolver(
val inheritedDeprecations = listOfNotNull(deprecationByOverridden(descriptor))
when (inheritedDeprecations.isNotEmpty()) {
true -> when (languageVersionSettings.supportsFeature(LanguageFeature.StopPropagatingDeprecationThroughOverrides)) {
true -> DeprecationInfo(emptyList(), hasInheritedDeprecations = true, inheritedDeprecations)
true -> DeprecationInfo(
inheritedDeprecations.filter { it.forcePropagationToOverrides },
hasInheritedDeprecations = true,
inheritedDeprecations
)
false -> DeprecationInfo(inheritedDeprecations, hasInheritedDeprecations = true)
}
false -> DeprecationInfo.EMPTY
@@ -167,7 +171,8 @@ class DeprecationResolver(
traverse(root)
if (hasUndeprecatedOverridden || deprecations.isEmpty()) return null
if (deprecations.isEmpty()) return null
if (hasUndeprecatedOverridden && deprecations.none { it.forcePropagationToOverrides }) return null
// We might've filtered out not-propagating deprecations already in the initializer of `deprecationsByAnnotation` in the code above.
// But it would lead to treating Java overridden as not-deprecated at all that works controversially in case of mixed J/K override: