diff --git a/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiMetadataProcessor.kt b/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiMetadataProcessor.kt index 6e95df16337..c38c8a78c4c 100644 --- a/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiMetadataProcessor.kt +++ b/plugins/jvm-abi-gen/src/org/jetbrains/kotlin/jvm/abi/JvmAbiMetadataProcessor.kt @@ -46,6 +46,25 @@ fun abiMetadataProcessor(annotationVisitor: AnnotationVisitor): AnnotationVisito pkg.removePrivateDeclarations() KotlinClassMetadata.writeMultiFileClassPart(pkg, metadata.facadeClassName, metadataVersion, header.extraInt).annotationData } + null -> { + // TODO: maybe jvm-abi-gen should throw this exception by default, and not only in tests. + if (System.getProperty("idea.is.unit.test").toBoolean()) { + val actual = "${metadataVersion[0]}.${metadataVersion[1]}" + val expected = KotlinClassMetadata.COMPATIBLE_METADATA_VERSION.let { "${it[0]}.${it[1]}" } + throw AssertionError( + "jvm-abi-gen can't process class file with the new metadata version because the version of kotlinx-metadata-jvm " + + "it depends on is too old.\n" + + "Class file has metadata version $actual, but default metadata version of kotlinx-metadata-jvm is " + + "$expected, so it can process class files with metadata version up to +1 from that (because of " + + "Kotlin/JVM's one-version forward compatibility policy).\n" + + "To fix this error, ensure that jvm-abi-gen depends on the latest version of kotlinx-metadata-jvm.\n" + + "If this happens during the update of the default language version in the project, make sure that " + + "a version of kotlinx-metadata-jvm has been published that supports this version, and update " + + "\"versions.kotlinx-metadata-jvm\" in `gradle/versions.properties`." + ) + } + header + } else -> header } diff --git a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt index 5a4c03f2abf..f25f4750b34 100644 --- a/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt +++ b/plugins/jvm-abi-gen/test/org/jetbrains/kotlin/jvm/abi/BaseJvmAbiTest.kt @@ -7,6 +7,7 @@ package org.jetbrains.kotlin.jvm.abi import com.intellij.openapi.util.io.FileUtil import junit.framework.TestCase +import kotlinx.metadata.jvm.KotlinClassMetadata import org.jetbrains.kotlin.cli.common.ExitCode import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler import org.jetbrains.kotlin.codegen.CodegenTestUtil @@ -81,7 +82,18 @@ abstract class BaseJvmAbiTest : TestCase() { ).toTypedArray() destination = compilation.destinationDir.canonicalPath noSourceDebugExtension = InTextDirectivesUtils.findStringWithPrefixes(directives, "// NO_SOURCE_DEBUG_EXTENSION") != null - useK2 = InTextDirectivesUtils.findStringWithPrefixes(directives, "// USE_K2") != null + + if (InTextDirectivesUtils.findStringWithPrefixes(directives, "// USE_K2") != null) { + useK2 = true + + // Force metadata version 1.9 to circumvent the fact that kotlinx-metadata-jvm 0.6.0 has default metadata version 1.8, + // so it can read/write metadata with versions up to and including 1.9, yet K2 has metadata version 2.0+. + // This hack can be removed once jvm-abi-gen depends on kotlinx-metadata-jvm that can read/write metadata version 2.0. + // Without this hack, CompileAgainstJvmAbiTestGenerated.testInlineClassWithPrivateConstructorK2 currently fails. + if (KotlinClassMetadata.COMPATIBLE_METADATA_VERSION.take(2) == listOf(1, 8)) { + metadataVersion = "1.9" + } + } } val exitCode = compiler.exec(messageCollector, Services.EMPTY, args) if (exitCode != ExitCode.OK || messageCollector.errors.isNotEmpty()) {