diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt index a06a3ed1806..7f7fd9972d7 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/deserialization/JvmClassFileBasedSymbolProvider.kt @@ -100,10 +100,15 @@ class JvmClassFileBasedSymbolProvider( private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData? get() { // TODO: skipMetadataVersionCheck - val expectedMetadataVersion = session.languageVersionSettings.languageVersion.toMetadataVersion() - if (classHeader.metadataVersion.isCompatible(expectedMetadataVersion)) return null + val metadataVersionFromLanguageVersion = session.languageVersionSettings.languageVersion.toMetadataVersion() + if (classHeader.metadataVersion.isCompatible(metadataVersionFromLanguageVersion)) return null return IncompatibleVersionErrorData( - classHeader.metadataVersion, maxOf(expectedMetadataVersion, JvmMetadataVersion.INSTANCE.next()), location, classId + actualVersion = classHeader.metadataVersion, + compilerVersion = JvmMetadataVersion.INSTANCE, + languageVersion = metadataVersionFromLanguageVersion, + expectedVersion = metadataVersionFromLanguageVersion.lastSupportedVersionWithThisLanguageVersion(classHeader.metadataVersion.isStrictSemantics), + filePath = location, + classId = classId ) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java index 60e71d8dcaa..df65ee19ef9 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/diagnostics/rendering/DefaultErrorMessages.java @@ -439,8 +439,10 @@ public class DefaultErrorMessages { "{0} was compiled with an incompatible version of Kotlin. {1}", TO_STRING, (incompatibility, renderingContext) -> - "The binary version of its metadata is " + incompatibility.getActualVersion() + - ", expected version is " + incompatibility.getExpectedVersion() + ".\n" + + "The actual metadata version is " + incompatibility.getActualVersion() + + ", but the compiler version " + incompatibility.getCompilerVersion() + + (incompatibility.getLanguageVersion().equals(incompatibility.getCompilerVersion()) ? "" : " [with language version " + incompatibility.getLanguageVersion() + "]") + + " can read versions up to " + incompatibility.getExpectedVersion() + ".\n" + "The class is loaded from " + FileUtil.toSystemIndependentName(incompatibility.getFilePath()) ); diff --git a/compiler/testData/cli/jvm/wrongAbiVersion.out b/compiler/testData/cli/jvm/wrongAbiVersion.out index 1da5df439a7..1f595d07b4c 100644 --- a/compiler/testData/cli/jvm/wrongAbiVersion.out +++ b/compiler/testData/cli/jvm/wrongAbiVersion.out @@ -1,6 +1,6 @@ error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors compiler/testData/cli/jvm/wrongAbiVersionLib/bin/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 0.30.0, expected version is $ABI_VERSION$. -compiler/testData/cli/jvm/wrongAbiVersion.kt:3:12: error: class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 0.30.0, expected version is $ABI_VERSION$. +compiler/testData/cli/jvm/wrongAbiVersion.kt:3:12: error: class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. The actual metadata version is 0.30.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TESTDATA_DIR$/wrongAbiVersionLib/bin/ClassWithWrongAbiVersion.class fun foo(x: ClassWithWrongAbiVersion) { ^ diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt index 7c3f590c5d9..3ad212f2cbd 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/output.txt @@ -1,6 +1,6 @@ error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors $TMP_DIR$/library.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is $ABI_VERSION$. -compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:3:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:3:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 1.9.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION$. The class is loaded from $TMP_DIR$/library.jar!/a/C.class fun test(c: C) { ^ @@ -10,15 +10,15 @@ compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemant compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:5:5: error: unresolved reference: v v ^ -compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:5: error: class 'a.C' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:5: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 1.9.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION$. The class is loaded from $TMP_DIR$/library.jar!/a/C.class c.let { C() } ^ -compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:7: error: class 'a.C' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:7: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 1.9.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION$. The class is loaded from $TMP_DIR$/library.jar!/a/C.class c.let { C() } ^ -compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.9.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/strictMetadataVersionSemanticsOldVersion/source.kt:6:13: error: class 'a.C' was compiled with an incompatible version of Kotlin. The actual metadata version is 1.9.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION$. The class is loaded from $TMP_DIR$/library.jar!/a/C.class c.let { C() } ^ diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt index bdc554410ce..c83c16453dc 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt @@ -1,34 +1,34 @@ error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors $TMP_DIR$/library-after.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class fun baz(param: A, nested: A.Nested) { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:27: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:27: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class fun baz(param: A, nested: A.Nested) { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:29: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:5:29: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class fun baz(param: A, nested: A.Nested) { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val constructor = A() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:7:18: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:7:18: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val nested = A.Nested() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:7:20: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:7:20: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class val nested = A.Nested() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val methodCall = param.method() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val supertype = object : A() {} ^ diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/output.txt index e26ada18674..9e5a0161842 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/output.txt @@ -1,34 +1,34 @@ error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors $TMP_DIR$/library-after.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class fun baz(param: A, nested: A.Nested) { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:27: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:27: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class fun baz(param: A, nested: A.Nested) { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:29: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:29: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class fun baz(param: A, nested: A.Nested) { ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val constructor = A() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:18: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:18: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val nested = A.Nested() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:20: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:20: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class val nested = A.Nested() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val methodCall = param.method() ^ -compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$. +compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The actual metadata version is 42.0.0, but the compiler version $ABI_VERSION$ can read versions up to $ABI_VERSION_NEXT$. The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class val supertype = object : A() {} ^ diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java index a8897b0360e..67d22e9eab7 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java @@ -93,6 +93,9 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir { .replace(PathUtil.getKotlinPathsForDistDirectory().getHomePath().getParentFile().getAbsolutePath(), "$DIST_DIR$") .replace("expected version is " + JvmMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$") .replace("expected version is " + JsMetadataVersion.INSTANCE, "expected version is $ABI_VERSION$") + .replace("compiler version " + JvmMetadataVersion.INSTANCE, "compiler version $ABI_VERSION$") + .replace("up to " + JvmMetadataVersion.INSTANCE, "up to $ABI_VERSION$") + .replace("up to " + JvmMetadataVersion.INSTANCE_NEXT, "up to $ABI_VERSION_NEXT$") .replace("\\", "/") .replace(KotlinCompilerVersion.VERSION, "$VERSION$") .replace("\n" + Usage.BAT_DELIMITER_CHARACTERS_NOTE + "\n", "") diff --git a/core/compiler.common/src/org/jetbrains/kotlin/serialization/deserialization/IncompatibleVersionErrorData.kt b/core/compiler.common/src/org/jetbrains/kotlin/serialization/deserialization/IncompatibleVersionErrorData.kt index dd8bab6d6c1..588274d1d17 100644 --- a/core/compiler.common/src/org/jetbrains/kotlin/serialization/deserialization/IncompatibleVersionErrorData.kt +++ b/core/compiler.common/src/org/jetbrains/kotlin/serialization/deserialization/IncompatibleVersionErrorData.kt @@ -9,6 +9,8 @@ import org.jetbrains.kotlin.name.ClassId data class IncompatibleVersionErrorData( val actualVersion: T, + val compilerVersion: T, + val languageVersion: T, val expectedVersion: T, val filePath: String, val classId: ClassId diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt index a9acbaa0cbf..223362ad86e 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt @@ -85,7 +85,12 @@ class DeserializedDescriptorResolver { get() { if (skipMetadataVersionCheck || classHeader.metadataVersion.isCompatible(ownMetadataVersion)) return null return IncompatibleVersionErrorData( - classHeader.metadataVersion, maxOf(ownMetadataVersion.prev(), JvmMetadataVersion.INSTANCE), location, classId + actualVersion = classHeader.metadataVersion, + compilerVersion = JvmMetadataVersion.INSTANCE, + languageVersion = ownMetadataVersion, + expectedVersion = ownMetadataVersion.lastSupportedVersionWithThisLanguageVersion(classHeader.metadataVersion.isStrictSemantics), + filePath = location, + classId = classId ) } diff --git a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmMetadataVersion.kt b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmMetadataVersion.kt index a14a4d2e377..d05f51e15a6 100644 --- a/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmMetadataVersion.kt +++ b/core/metadata.jvm/src/org/jetbrains/kotlin/metadata/jvm/deserialization/JvmMetadataVersion.kt @@ -14,6 +14,13 @@ import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion class JvmMetadataVersion(versionArray: IntArray, val isStrictSemantics: Boolean) : BinaryVersion(*versionArray) { constructor(vararg numbers: Int) : this(numbers, isStrictSemantics = false) + fun lastSupportedVersionWithThisLanguageVersion(isStrictSemantics: Boolean): JvmMetadataVersion { + // * Compiler of deployVersion X (INSTANCE) with LV Y (metadataVersionFromLanguageVersion) + // * can read metadata with version <= max(X+1, Y) + val forwardCompatibility = if (isStrictSemantics) INSTANCE else INSTANCE_NEXT + return if (forwardCompatibility.newerThan(this)) forwardCompatibility else this + } + override fun isCompatibleWithCurrentCompilerVersion(): Boolean { return isCompatibleInternal(INSTANCE_NEXT) } @@ -21,10 +28,7 @@ class JvmMetadataVersion(versionArray: IntArray, val isStrictSemantics: Boolean) fun isCompatible(metadataVersionFromLanguageVersion: JvmMetadataVersion): Boolean { // Special case for bootstrap: 1.8 can read 2.0 if (major == 2 && minor == 0 && INSTANCE.major == 1 && INSTANCE.minor == 8) return true - // * Compiler of deployVersion X (INSTANCE) with LV Y (metadataVersionFromLanguageVersion) - // * can read metadata with version <= max(X+1, Y) - val forwardCompatibility = if (isStrictSemantics) INSTANCE else INSTANCE_NEXT - val limitVersion = maxOf(forwardCompatibility, metadataVersionFromLanguageVersion) + val limitVersion = metadataVersionFromLanguageVersion.lastSupportedVersionWithThisLanguageVersion(isStrictSemantics) return isCompatibleInternal(limitVersion) } @@ -34,24 +38,28 @@ class JvmMetadataVersion(versionArray: IntArray, val isStrictSemantics: Boolean) // The same for 0.* if (major == 0) return false // Otherwise we just compare with the given limitVersion - return this <= limitVersion + return !newerThan(limitVersion) } - fun next(): JvmMetadataVersion { - if (minor < 9 || major > 1) return JvmMetadataVersion(major, minor + 1, 0) - return JvmMetadataVersion(2, 0, 0) - } + fun next(): JvmMetadataVersion = + if (major == 1 && minor == 9) JvmMetadataVersion(2, 0, 0) + else JvmMetadataVersion(major, minor + 1, 0) - fun prev(): JvmMetadataVersion { - if (minor > 0) return JvmMetadataVersion(major, minor - 1, 0) - return JvmMetadataVersion(major - 1, 9, 0) + private fun newerThan(other: JvmMetadataVersion): Boolean { + return when { + major > other.major -> true + major < other.major -> false + minor > other.minor -> true + else -> false + } } companion object { @JvmField val INSTANCE = JvmMetadataVersion(1, 8, 0) - private val INSTANCE_NEXT = INSTANCE.next() + @JvmField + val INSTANCE_NEXT = INSTANCE.next() @JvmField val INVALID_VERSION = JvmMetadataVersion() diff --git a/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt b/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt index e2ad65fddc3..1106ff859b9 100644 --- a/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt +++ b/core/metadata/src/org/jetbrains/kotlin/metadata/deserialization/BinaryVersion.kt @@ -14,7 +14,7 @@ package org.jetbrains.kotlin.metadata.deserialization * - Patch version can be increased freely and is only supposed to be used for debugging. Increase the patch version when you * make a change to binaries which is both forward- and backward compatible. */ -abstract class BinaryVersion(private vararg val numbers: Int) : Comparable { +abstract class BinaryVersion(private vararg val numbers: Int) { val major: Int = numbers.getOrNull(0) ?: UNKNOWN val minor: Int = numbers.getOrNull(1) ?: UNKNOWN val patch: Int = numbers.getOrNull(2) ?: UNKNOWN @@ -87,18 +87,6 @@ abstract class BinaryVersion(private vararg val numbers: Int) : Comparable other.major -> 1 - major < other.major -> -1 - minor > other.minor -> 1 - minor < other.minor -> -1 - patch > other.patch -> 1 - patch < other.patch -> -1 - else -> 0 - } - } - companion object { const val MAX_LENGTH = 1024 private const val UNKNOWN = -1 diff --git a/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api b/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api index 72dd618cabb..5f3ef71a70c 100644 --- a/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api +++ b/libraries/kotlinx-metadata/jvm/api/kotlinx-metadata-jvm.api @@ -1366,7 +1366,7 @@ public final class kotlinx/metadata/jvm/KotlinClassMetadata$Unknown : kotlinx/me public final class kotlinx/metadata/jvm/KotlinModuleMetadata { public static final field Companion Lkotlinx/metadata/jvm/KotlinModuleMetadata$Companion; - public fun ([BLkotlinx/metadata/internal/metadata/jvm/deserialization/JvmMetadataVersion;)V + public fun ([B)V public final fun accept (Lkotlinx/metadata/jvm/KmModuleVisitor;)V public final fun getBytes ()[B public static final fun read ([B)Lkotlinx/metadata/jvm/KotlinModuleMetadata; diff --git a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinModuleMetadata.kt b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinModuleMetadata.kt index bcf5bd011b9..65c7b564979 100644 --- a/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinModuleMetadata.kt +++ b/libraries/kotlinx-metadata/jvm/src/kotlinx/metadata/jvm/KotlinModuleMetadata.kt @@ -25,13 +25,12 @@ import org.jetbrains.kotlin.metadata.jvm.deserialization.serializeToByteArray * * @property bytes the byte array representing the contents of a `.kotlin_module` file */ -class KotlinModuleMetadata(@Suppress("MemberVisibilityCanBePrivate") val bytes: ByteArray, jvmMetadataVersion: JvmMetadataVersion) { +class KotlinModuleMetadata(@Suppress("MemberVisibilityCanBePrivate") val bytes: ByteArray) { @get:IgnoreInApiDump internal val data: ModuleMapping = ModuleMapping.loadModuleMapping( bytes, javaClass.name, skipMetadataVersionCheck = false, - isJvmPackageNameSupported = true, - metadataVersionFromLanguageVersion = jvmMetadataVersion + isJvmPackageNameSupported = true ) { // TODO: report incorrect versions of modules } @@ -90,7 +89,7 @@ class KotlinModuleMetadata(@Suppress("MemberVisibilityCanBePrivate") val bytes: */ @Deprecated("Writer API is deprecated as excessive and cumbersome. Please use KotlinModuleMetadata.write(kmModule, metadataVersion)") fun write(metadataVersion: IntArray = COMPATIBLE_METADATA_VERSION): KotlinModuleMetadata = - KotlinModuleMetadata(b.build().serializeToByteArray(JvmMetadataVersion(*metadataVersion), 0), jvmMetadataVersion) + KotlinModuleMetadata(b.build().serializeToByteArray(JvmMetadataVersion(*metadataVersion), 0)) } /** @@ -129,7 +128,7 @@ class KotlinModuleMetadata(@Suppress("MemberVisibilityCanBePrivate") val bytes: @JvmStatic fun read(bytes: ByteArray): KotlinModuleMetadata? { try { - val result = KotlinModuleMetadata(bytes, JvmMetadataVersion.INSTANCE) + val result = KotlinModuleMetadata(bytes) if (result.data == ModuleMapping.EMPTY) return null if (result.data == ModuleMapping.CORRUPTED) {