Support multiple version requirements on single element
This commit is contained in:
+6
-6
@@ -76,9 +76,9 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
||||
it is CallableMemberDescriptor && it.hasJvmDefaultAnnotation()
|
||||
}
|
||||
) {
|
||||
assert(!builder.hasVersionRequirement()) { "VersionRequirement should be empty for $classDescriptor" }
|
||||
builder.versionRequirement =
|
||||
writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
builder.addVersionRequirement(
|
||||
writeVersionRequirement(1, 2, 40, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -183,9 +183,9 @@ class JvmSerializerExtension(private val bindings: JvmSerializationBindings, sta
|
||||
if (descriptor.isJvmFieldPropertyInInterfaceCompanion()) {
|
||||
proto.setExtension(JvmProtoBuf.flags, JvmFlags.getPropertyFlags(true))
|
||||
|
||||
assert(!proto.hasVersionRequirement()) { "VersionRequirement should be empty for $descriptor" }
|
||||
proto.versionRequirement =
|
||||
writeVersionRequirement(1, 2, 70, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
proto.addVersionRequirement(
|
||||
writeVersionRequirement(1, 2, 70, ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION, versionRequirementTable)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -310,7 +310,9 @@ class DeprecationResolver(
|
||||
result.add(deprecation)
|
||||
}
|
||||
|
||||
getDeprecationByVersionRequirement(target)?.let(result::add)
|
||||
for (deprecation in getDeprecationByVersionRequirement(target)) {
|
||||
result.add(deprecation)
|
||||
}
|
||||
getDeprecationByCoroutinesVersion(target)?.let(result::add)
|
||||
}
|
||||
|
||||
@@ -356,30 +358,33 @@ class DeprecationResolver(
|
||||
DeprecatedExperimentalCoroutine(target)
|
||||
else null
|
||||
|
||||
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): DeprecatedByVersionRequirement? {
|
||||
private fun getDeprecationByVersionRequirement(target: DeclarationDescriptor): List<DeprecatedByVersionRequirement> {
|
||||
fun createVersion(version: String): MavenComparableVersion? = try {
|
||||
MavenComparableVersion(version)
|
||||
} catch (e: Exception) {
|
||||
null
|
||||
}
|
||||
|
||||
val versionRequirement =
|
||||
(target as? DeserializedMemberDescriptor)?.versionRequirement
|
||||
?: (target as? DeserializedClassDescriptor)?.versionRequirement
|
||||
?: return null
|
||||
val requiredVersion = createVersion(versionRequirement.version.asString())
|
||||
val currentVersion = when (versionRequirement.kind) {
|
||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION ->
|
||||
MavenComparableVersion(languageVersionSettings.languageVersion.versionString)
|
||||
ProtoBuf.VersionRequirement.VersionKind.API_VERSION ->
|
||||
languageVersionSettings.apiVersion.version
|
||||
ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION ->
|
||||
KotlinCompilerVersion.getVersion()?.substringBefore('-')?.let(::createVersion)
|
||||
else -> null
|
||||
val versionRequirements =
|
||||
(target as? DeserializedMemberDescriptor)?.versionRequirements
|
||||
?: (target as? DeserializedClassDescriptor)?.versionRequirements
|
||||
?: return emptyList()
|
||||
|
||||
return versionRequirements.mapNotNull { versionRequirement ->
|
||||
val requiredVersion = createVersion(versionRequirement.version.asString())
|
||||
val currentVersion = when (versionRequirement.kind) {
|
||||
ProtoBuf.VersionRequirement.VersionKind.LANGUAGE_VERSION ->
|
||||
MavenComparableVersion(languageVersionSettings.languageVersion.versionString)
|
||||
ProtoBuf.VersionRequirement.VersionKind.API_VERSION ->
|
||||
languageVersionSettings.apiVersion.version
|
||||
ProtoBuf.VersionRequirement.VersionKind.COMPILER_VERSION ->
|
||||
KotlinCompilerVersion.getVersion()?.substringBefore('-')?.let(::createVersion)
|
||||
else -> null
|
||||
}
|
||||
if (currentVersion != null && currentVersion < requiredVersion)
|
||||
DeprecatedByVersionRequirement(versionRequirement, target)
|
||||
else
|
||||
null
|
||||
}
|
||||
if (currentVersion != null && currentVersion < requiredVersion) {
|
||||
return DeprecatedByVersionRequirement(versionRequirement, target)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
+22
-26
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.builtins.transformSuspendFunctionToRuntimeFunctionTy
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.Annotated
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.metadata.ProtoBuf
|
||||
import org.jetbrains.kotlin.metadata.deserialization.Flags
|
||||
import org.jetbrains.kotlin.metadata.deserialization.VersionRequirement
|
||||
@@ -141,10 +142,7 @@ class DescriptorSerializer private constructor(
|
||||
builder.typeTable = typeTableProto
|
||||
}
|
||||
|
||||
val requirement = serializeVersionRequirement(classDescriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
}
|
||||
builder.addAllVersionRequirement(serializeVersionRequirements(classDescriptor))
|
||||
|
||||
extension.serializeClass(classDescriptor, builder, versionRequirementTable)
|
||||
|
||||
@@ -235,11 +233,10 @@ class DescriptorSerializer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val requirement = serializeVersionRequirement(descriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirementDependingOnCoroutinesVersion()
|
||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||
|
||||
if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||
}
|
||||
|
||||
extension.serializeProperty(descriptor, builder, versionRequirementTable)
|
||||
@@ -305,11 +302,10 @@ class DescriptorSerializer private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val requirement = serializeVersionRequirement(descriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirementDependingOnCoroutinesVersion()
|
||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||
|
||||
if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||
}
|
||||
|
||||
contractSerializer.serializeContractOfFunctionIfAny(descriptor, builder, this)
|
||||
@@ -335,11 +331,10 @@ class DescriptorSerializer private constructor(
|
||||
builder.addValueParameter(local.valueParameter(valueParameterDescriptor))
|
||||
}
|
||||
|
||||
val requirement = serializeVersionRequirement(descriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
} else if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.versionRequirement = writeVersionRequirementDependingOnCoroutinesVersion()
|
||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||
|
||||
if (descriptor.isSuspendOrHasSuspendTypesInSignature()) {
|
||||
builder.addVersionRequirement(writeVersionRequirementDependingOnCoroutinesVersion())
|
||||
}
|
||||
|
||||
extension.serializeConstructor(descriptor, builder)
|
||||
@@ -392,10 +387,7 @@ class DescriptorSerializer private constructor(
|
||||
builder.setExpandedType(local.type(expandedType))
|
||||
}
|
||||
|
||||
val requirement = serializeVersionRequirement(descriptor)
|
||||
if (requirement != null) {
|
||||
builder.versionRequirement = requirement
|
||||
}
|
||||
builder.addAllVersionRequirement(serializeVersionRequirements(descriptor))
|
||||
|
||||
for (annotation in descriptor.nonSourceAnnotations) {
|
||||
builder.addAnnotation(extension.annotationSerializer.serializeAnnotation(annotation))
|
||||
@@ -633,9 +625,13 @@ class DescriptorSerializer private constructor(
|
||||
return writeVersionRequirement(major, minor, patch, versionKind, versionRequirementTable)
|
||||
}
|
||||
|
||||
// Returns index into versionRequirementTable, or null if there's no @RequireKotlin on the descriptor
|
||||
private fun serializeVersionRequirement(descriptor: DeclarationDescriptor): Int? {
|
||||
val annotation = descriptor.annotations.findAnnotation(RequireKotlinNames.FQ_NAME) ?: return null
|
||||
// Returns a list of indices into versionRequirementTable, or empty list if there's no @RequireKotlin on the descriptor
|
||||
private fun serializeVersionRequirements(descriptor: DeclarationDescriptor): List<Int> =
|
||||
descriptor.annotations
|
||||
.filter { it.fqName == RequireKotlinNames.FQ_NAME }
|
||||
.mapNotNull(::serializeVersionRequirementFromRequireKotlin)
|
||||
|
||||
private fun serializeVersionRequirementFromRequireKotlin(annotation: AnnotationDescriptor): Int? {
|
||||
val args = annotation.allValueArguments
|
||||
|
||||
val versionString = (args[RequireKotlinNames.VERSION] as? StringValue)?.value ?: return null
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
|
||||
package a
|
||||
|
||||
import kotlin.internal.RequireKotlin as RK
|
||||
import kotlin.internal.RequireKotlinVersionKind as K
|
||||
|
||||
@RK("42.33", message = "This declaration is only supported since Kotlin 42.33")
|
||||
@RK("40.34", versionKind = K.API_VERSION)
|
||||
@RK("45.35")
|
||||
class A
|
||||
|
||||
@RK("42.33", message = "This declaration is only supported since Kotlin 42.33")
|
||||
@RK("40.34", versionKind = K.API_VERSION)
|
||||
@RK("45.35")
|
||||
@RK("1.1")
|
||||
fun f() {}
|
||||
|
||||
@RK("42.33", message = "This declaration is only supported since Kotlin 42.33")
|
||||
@RK("40.34", versionKind = K.API_VERSION)
|
||||
@RK("45.35")
|
||||
val p = ""
|
||||
|
||||
@RK("42.33", message = "This declaration is only supported since Kotlin 42.33")
|
||||
@RK("40.34", versionKind = K.API_VERSION)
|
||||
@RK("45.35")
|
||||
@RK("1.1")
|
||||
typealias TA = String
|
||||
+37
@@ -0,0 +1,37 @@
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:3:13: error: 'A' is only available since Kotlin 42.33 and cannot be used in Kotlin 1.2. This declaration is only supported since Kotlin 42.33
|
||||
fun test(a: A): TA {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:3:13: error: 'A' is only available since Kotlin 40.34 and cannot be used in Kotlin 1.2
|
||||
fun test(a: A): TA {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:3:13: error: 'A' is only available since Kotlin 45.35 and cannot be used in Kotlin 1.2
|
||||
fun test(a: A): TA {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:3:17: error: 'typealias TA = String' is only available since Kotlin 42.33 and cannot be used in Kotlin 1.2. This declaration is only supported since Kotlin 42.33
|
||||
fun test(a: A): TA {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:3:17: error: 'typealias TA = String' is only available since Kotlin 40.34 and cannot be used in Kotlin 1.2
|
||||
fun test(a: A): TA {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:3:17: error: 'typealias TA = String' is only available since Kotlin 45.35 and cannot be used in Kotlin 1.2
|
||||
fun test(a: A): TA {
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:4:5: error: 'f(): Unit' is only available since Kotlin 42.33 and cannot be used in Kotlin 1.2. This declaration is only supported since Kotlin 42.33
|
||||
f()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:4:5: error: 'f(): Unit' is only available since Kotlin 40.34 and cannot be used in Kotlin 1.2
|
||||
f()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:4:5: error: 'f(): Unit' is only available since Kotlin 45.35 and cannot be used in Kotlin 1.2
|
||||
f()
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:5:12: error: 'p: String' is only available since Kotlin 42.33 and cannot be used in Kotlin 1.2. This declaration is only supported since Kotlin 42.33
|
||||
return p
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:5:12: error: 'p: String' is only available since Kotlin 40.34 and cannot be used in Kotlin 1.2
|
||||
return p
|
||||
^
|
||||
compiler/testData/compileKotlinAgainstCustomBinaries/requireKotlin/source.kt:5:12: error: 'p: String' is only available since Kotlin 45.35 and cannot be used in Kotlin 1.2
|
||||
return p
|
||||
^
|
||||
COMPILATION_ERROR
|
||||
@@ -0,0 +1,6 @@
|
||||
import a.*
|
||||
|
||||
fun test(a: A): TA {
|
||||
f()
|
||||
return p
|
||||
}
|
||||
+4
@@ -296,6 +296,10 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
|
||||
doTestKotlinLibraryWithWrongMetadataVersionJs("library", "-Xskip-metadata-version-check")
|
||||
}
|
||||
|
||||
fun testRequireKotlin() {
|
||||
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
|
||||
}
|
||||
|
||||
fun testRequireKotlinInNestedClasses() {
|
||||
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
|
||||
}
|
||||
|
||||
@@ -37,8 +37,8 @@ abstract class AbstractVersionRequirementTest : TestCaseWithTmpdir() {
|
||||
val descriptor = module.findUnambiguousDescriptorByFqName(fqName)
|
||||
|
||||
val requirement = when (descriptor) {
|
||||
is DeserializedMemberDescriptor -> descriptor.versionRequirement
|
||||
is DeserializedClassDescriptor -> descriptor.versionRequirement
|
||||
is DeserializedMemberDescriptor -> descriptor.versionRequirements.single()
|
||||
is DeserializedClassDescriptor -> descriptor.versionRequirements.single()
|
||||
else -> throw AssertionError("Unknown descriptor: $descriptor")
|
||||
} ?: throw AssertionError("No VersionRequirement for $descriptor")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user