diff --git a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt index 3c333865090..de30dc58c27 100644 --- a/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt +++ b/compiler/builtins-serializer/src/org/jetbrains/kotlin/serialization/builtins/BuiltInsSerializer.kt @@ -22,6 +22,7 @@ import com.intellij.psi.search.GlobalSearchScope import org.jetbrains.kotlin.analyzer.ModuleContent import org.jetbrains.kotlin.analyzer.ModuleInfo import org.jetbrains.kotlin.builtins.BuiltInsSerializedResourcePaths +import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles @@ -149,11 +150,9 @@ public class BuiltInsSerializer(private val dependOnOldBuiltIns: Boolean) { val builtinsFileStream = ByteArrayOutputStream() with(DataOutputStream(builtinsFileStream)) { - // TODO: write version properly - writeInt(3) - writeInt(1) - writeInt(0) - writeInt(0) + val version = BuiltinsPackageFragment.VERSION.toArray() + writeInt(version.size) + version.forEach { writeInt(it) } } message.build().writeTo(builtinsFileStream) write(destDir, BuiltInsSerializedResourcePaths.getBuiltInsFilePath(fqName), builtinsFileStream) diff --git a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AbiVersionUtil.java b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AbiVersionUtil.java index 1fa031941ce..a634d60bf6e 100644 --- a/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AbiVersionUtil.java +++ b/core/descriptor.loader.java/src/org/jetbrains/kotlin/load/java/AbiVersionUtil.java @@ -23,8 +23,7 @@ public final class AbiVersionUtil { public static final BinaryVersion INVALID_VERSION = BinaryVersion.create(new int[0]); public static boolean isAbiVersionCompatible(@NotNull BinaryVersion actual) { - return actual.getMajor() == JvmAbi.VERSION.getMajor() && - actual.getMinor() <= JvmAbi.VERSION.getMinor(); + return actual.isCompatibleTo(JvmAbi.VERSION); } private AbiVersionUtil() { diff --git a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt index d745744f919..1713d9dbc74 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/builtins/BuiltinsPackageFragment.kt @@ -21,6 +21,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.serialization.ProtoBuf import org.jetbrains.kotlin.serialization.builtins.BuiltInsProtoBuf +import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment import org.jetbrains.kotlin.storage.StorageManager import java.io.InputStream @@ -35,4 +36,9 @@ public class BuiltinsPackageFragment( protected override fun loadClassNames(packageProto: ProtoBuf.Package): Collection { return packageProto.getExtension(BuiltInsProtoBuf.className)?.map { id -> nameResolver.getName(id) } ?: listOf() } + + companion object { + // Advance this version when the common or builtins-specific binary metadata format is changed + val VERSION = BinaryVersion.create(1, 0, 0) + } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/BinaryVersion.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/BinaryVersion.kt index d3e0ce538f9..5690c80fe1f 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/BinaryVersion.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/BinaryVersion.kt @@ -25,6 +25,17 @@ data class BinaryVersion private constructor( fun toArray(): IntArray = intArrayOf(major, minor, patch, *rest.toIntArray()) + /** + * Returns true if this version of some format loaded from some binaries is compatible + * to the expected version of that format in the current compiler. + * + * @param ourVersion the version of this format in the current compiler + */ + fun isCompatibleTo(ourVersion: BinaryVersion): Boolean { + return if (major == 0) ourVersion.major == 0 && minor == ourVersion.minor + else major == ourVersion.major && minor <= ourVersion.minor + } + override fun toString(): String { val versions = toArray().takeWhile { it != UNKNOWN } return if (versions.isEmpty()) "unknown" else versions.joinToString(".") diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt index f300c494582..87e1165f546 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializedPackageFragment.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.serialization.deserialization +import org.jetbrains.kotlin.builtins.BuiltinsPackageFragment import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl import org.jetbrains.kotlin.name.FqName @@ -40,15 +41,14 @@ public abstract class DeserializedPackageFragment( val builtinsMessage = serializedResourcePaths.getBuiltInsFilePath(fqName)?.let(loadResource)?.let { stream -> val dataInput = DataInputStream(stream) - val version = (1..dataInput.readInt()).map { dataInput.readInt() } + val version = BinaryVersion.create((1..dataInput.readInt()).map { dataInput.readInt() }.toIntArray()) - // TODO: check version correctly - if (!(version.size == 3 && version.let { - val (major, minor, patch) = it - major == 1 && minor == 0 && patch == 0 - })) { + if (!version.isCompatibleTo(BuiltinsPackageFragment.VERSION)) { + // TODO: report a proper diagnostic throw UnsupportedOperationException( - "Kotlin built-in definition format version is not supported: expected 1.0.0, actual ${version.joinToString(".")}" + "Kotlin built-in definition format version is not supported: " + + "expected ${BuiltinsPackageFragment.VERSION}, actual $version. " + + "Please update Kotlin" ) }