From 9970851684ab772275bd44a12507da772d395f4e Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Fri, 5 Mar 2021 18:37:00 +0100 Subject: [PATCH] Restore writing bytecode version to metadata for LV < 1.5 #KT-45323 Fixed --- .../jetbrains/kotlin/build/JvmBuildMetaInfo.kt | 1 + .../kotlin/codegen/writeAnnotationUtil.kt | 6 ++++-- .../load/kotlin}/JvmBytecodeBinaryVersion.kt | 15 +++++++++++---- .../kotlin/jps/incremental/CacheVersionTest.kt | 2 +- .../kotlin/jps/incremental/CacheVersionManager.kt | 2 +- 5 files changed, 18 insertions(+), 8 deletions(-) rename {build-common/src/org/jetbrains/kotlin/build => compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin}/JvmBytecodeBinaryVersion.kt (51%) diff --git a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt index f1ecc3eb9d5..00a64474419 100644 --- a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt @@ -16,6 +16,7 @@ package org.jetbrains.kotlin.build +import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion /** diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt index dd4c80fbf71..c33ddbc0573 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt @@ -19,8 +19,8 @@ package org.jetbrains.kotlin.codegen import org.jetbrains.kotlin.codegen.state.GenerationState import org.jetbrains.kotlin.config.JvmAnalysisFlags import org.jetbrains.kotlin.load.java.JvmAnnotationNames +import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader -import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmBytecodeBinaryVersion import org.jetbrains.org.objectweb.asm.AnnotationVisitor fun writeKotlinMetadata( @@ -32,7 +32,9 @@ fun writeKotlinMetadata( ) { val av = cb.newAnnotation(JvmAnnotationNames.METADATA_DESC, true) av.visit(JvmAnnotationNames.METADATA_VERSION_FIELD_NAME, state.metadataVersion.toArray()) - av.visit(JvmAnnotationNames.BYTECODE_VERSION_FIELD_NAME, JvmBytecodeBinaryVersion.INSTANCE.toArray()) + if (!state.metadataVersion.isAtLeast(1, 5, 0)) { + av.visit("bv", JvmBytecodeBinaryVersion.INSTANCE.toArray()) + } av.visit(JvmAnnotationNames.KIND_FIELD_NAME, kind.id) var flags = extraFlags if (state.languageVersionSettings.isPreRelease()) { diff --git a/build-common/src/org/jetbrains/kotlin/build/JvmBytecodeBinaryVersion.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JvmBytecodeBinaryVersion.kt similarity index 51% rename from build-common/src/org/jetbrains/kotlin/build/JvmBytecodeBinaryVersion.kt rename to compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JvmBytecodeBinaryVersion.kt index 45f8e71db95..e087b1e0ab5 100644 --- a/build-common/src/org/jetbrains/kotlin/build/JvmBytecodeBinaryVersion.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/load/kotlin/JvmBytecodeBinaryVersion.kt @@ -3,19 +3,26 @@ * 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.build +package org.jetbrains.kotlin.load.kotlin /** * Bytecode version was in the Kotlin metadata ([Metadata.bytecodeVersion]) since 1.0, but it was never used meaningfully in the compiler, - * outside of one very special case regarding experimental coroutines, which is now obsolete. It is still used in incremental compilation - * caches though. We should probably just pretend that the bytecode version of any Kotlin file from now on is equal to the latest observed - * bytecode version, `1.0.3` (see [INSTANCE]). + * outside of one very special case regarding experimental coroutines, which is now obsolete. + * It is still used for two reasons: + * 1) We write the latest observed bytecode version, `1.0.3` (see [INSTANCE]), to class files if metadata version is less than 1.5. + * The reason is that Kotlin compilers of versions 1.0.0-1.3.72 can still read these class files, and they had a strict check which + * results in a compilation error if there's no bytecode version in the `@Metadata` annotation (see KT-45323). + * This will not be needed at the moment when the earliest supported language version becomes 1.5, i.e. in Kotlin 1.7. + * 2) It's stored in persistent incremental compilation caches. We can probably simply remove it and increase the cache version there. + * Once both these usages are dealt with, this class can be removed. */ class JvmBytecodeBinaryVersion(vararg numbers: Int) { val major: Int = numbers.getOrNull(0) ?: -1 val minor: Int = numbers.getOrNull(1) ?: -1 val patch: Int = numbers.getOrNull(2) ?: -1 + fun toArray(): IntArray = intArrayOf(major, minor, patch) + override fun toString(): String = buildString { append(major) if (minor != -1) { diff --git a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/CacheVersionTest.kt b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/CacheVersionTest.kt index 0e309c86f6d..30a361cae7b 100644 --- a/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/CacheVersionTest.kt +++ b/jps-plugin/jps-tests/test/org/jetbrains/kotlin/jps/incremental/CacheVersionTest.kt @@ -5,7 +5,7 @@ package org.jetbrains.kotlin.jps.incremental -import org.jetbrains.kotlin.build.JvmBytecodeBinaryVersion +import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import org.junit.Assert.assertEquals import org.junit.Test diff --git a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/CacheVersionManager.kt b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/CacheVersionManager.kt index 8318ce3f53d..df3cddd57e4 100644 --- a/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/CacheVersionManager.kt +++ b/jps-plugin/src/org/jetbrains/kotlin/jps/incremental/CacheVersionManager.kt @@ -6,7 +6,7 @@ package org.jetbrains.kotlin.jps.incremental import org.jetbrains.annotations.TestOnly -import org.jetbrains.kotlin.build.JvmBytecodeBinaryVersion +import org.jetbrains.kotlin.load.kotlin.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion import java.io.File import java.io.IOException