diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinIrSignatureVersion.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinIrSignatureVersion.kt new file mode 100644 index 00000000000..b8b509802c4 --- /dev/null +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinIrSignatureVersion.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.library + +/** + * Describes how signatures of IR declarations are serialized in a KLIB. + */ +data class KotlinIrSignatureVersion(val number: Int) { + + companion object { + + /** + * Signatures are represented by the [org.jetbrains.kotlin.ir.util.IdSignature] class. Signatures of public declarations + * ([org.jetbrains.kotlin.ir.util.IdSignature.CommonSignature]) have no description. + * Only their numeric identifier participates in linkage. + */ + val V1 = KotlinIrSignatureVersion(1) + + /** + * Like [V1], but signatures of public declarations have a description along with a numeric identifier that can be used for showing + * more readable ABI dumps and linker errors. + * Linkage is still performed using only the numeric identifier, thus making [V2] fully compatible with [V1]. + */ + val V2 = KotlinIrSignatureVersion(2) + + /** + * The signature versions that this compiler emits. + */ + val CURRENTLY_SUPPORTED_VERSIONS = setOf(V1, V2) + } +} + +internal fun String.parseIrSignatureVersions(): Set = + split(",") + .mapTo(hashSetOf()) { KotlinIrSignatureVersion(it.toInt()) } + +internal fun Set.toManifestValue(): String = + sortedBy { it.number } + .joinToString(separator = ",") { it.number.toString() } + diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt index 6a6c8079c11..c5c312a9c97 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibrary.kt @@ -10,6 +10,11 @@ import org.jetbrains.kotlin.konan.properties.propertyList const val KLIB_PROPERTY_ABI_VERSION = "abi_version" const val KLIB_PROPERTY_COMPILER_VERSION = "compiler_version" +/** + * A set of values of [org.jetbrains.kotlin.library.KotlinIrSignatureVersion]. + */ +const val KLIB_PROPERTY_IR_SIGNATURE_VERSIONS = "ir_signature_versions" + /** * [org.jetbrains.kotlin.library.metadata.KlibMetadataVersion] */ diff --git a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryVersioning.kt b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryVersioning.kt index a2c0c9a101e..daf23f0927b 100644 --- a/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryVersioning.kt +++ b/compiler/util-klib/src/org/jetbrains/kotlin/library/KotlinLibraryVersioning.kt @@ -7,13 +7,21 @@ data class KotlinLibraryVersioning( val compilerVersion: String?, val abiVersion: KotlinAbiVersion?, val metadataVersion: String?, -) + val irSignatureVersions: Set = KotlinIrSignatureVersion.CURRENTLY_SUPPORTED_VERSIONS, +) { + init { + require(irSignatureVersions.isNotEmpty()) { + "Signature versions must not be empty!" + } + } +} fun Properties.writeKonanLibraryVersioning(versions: KotlinLibraryVersioning) { versions.abiVersion?.let { this.setProperty(KLIB_PROPERTY_ABI_VERSION, it.toString()) } versions.libraryVersion?.let { this.setProperty(KLIB_PROPERTY_LIBRARY_VERSION, it) } versions.compilerVersion?.let { this.setProperty(KLIB_PROPERTY_COMPILER_VERSION, it) } versions.metadataVersion?.let { this.setProperty(KLIB_PROPERTY_METADATA_VERSION, it) } + this.setProperty(KLIB_PROPERTY_IR_SIGNATURE_VERSIONS, versions.irSignatureVersions.toManifestValue()) } fun Properties.readKonanLibraryVersioning(): KotlinLibraryVersioning { @@ -22,10 +30,16 @@ fun Properties.readKonanLibraryVersioning(): KotlinLibraryVersioning { val compilerVersion = this.getProperty(KLIB_PROPERTY_COMPILER_VERSION) val metadataVersion = this.getProperty(KLIB_PROPERTY_METADATA_VERSION) + // If there is no such property in the manifest, it means that the manifest was generated by an older version of the compiler, + // meaning that it only contains v1 signatures. + val irSignatureVersions = this.getProperty(KLIB_PROPERTY_IR_SIGNATURE_VERSIONS)?.parseIrSignatureVersions() + ?: setOf(KotlinIrSignatureVersion.V1) + return KotlinLibraryVersioning( abiVersion = abiVersion, libraryVersion = libraryVersion, compilerVersion = compilerVersion, metadataVersion = metadataVersion, + irSignatureVersions = irSignatureVersions, ) }