Update JVM metadata version to 1.5.0

Improve the test which checks that we use correct metadata version if
`-language-version` is passed by checking all supported language
versions.

The change in libraries/reflect/build.gradle.kts is needed because
kotlinx-metadata-jvm of version 0.1.0 is based on pre-1.4 Kotlin, which
doesn't support the new module file metadata generated with metadata
version 1.4 and later, and module files need to be readable there to be
able to transform them for the shadow plugin.

Similarly override dependency on kotlinx-metadata-jvm in the
binary-compatibility-validator module.
This commit is contained in:
Alexander Udalov
2021-02-15 18:07:38 +01:00
parent dbadd5846a
commit 8c95b78346
6 changed files with 57 additions and 17 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
import org.jetbrains.kotlin.codegen.optimization.OptimizationClassBuilderFactory
import org.jetbrains.kotlin.codegen.serialization.JvmSerializationBindings
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.LanguageVersion.*
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ScriptDescriptor
@@ -49,6 +50,7 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeApproximator
import org.jetbrains.org.objectweb.asm.Type
import java.io.File
import java.util.*
class GenerationState private constructor(
val project: Project,
@@ -320,8 +322,7 @@ class GenerationState private constructor(
val metadataVersion =
configuration.get(CommonConfigurationKeys.METADATA_VERSION)
?: if (languageVersionSettings.languageVersion >= LanguageVersion.LATEST_STABLE) JvmMetadataVersion.INSTANCE
else JvmMetadataVersion(1, 1, 18)
?: LANGUAGE_TO_METADATA_VERSION.getValue(languageVersionSettings.languageVersion)
val abiStability = configuration.get(JVMConfigurationKeys.ABI_STABILITY)
@@ -392,6 +393,24 @@ class GenerationState private constructor(
private fun shouldOnlyCollectSignatures(origin: JvmDeclarationOrigin) =
classBuilderMode == ClassBuilderMode.LIGHT_CLASSES && origin.originKind in doNotGenerateInLightClassMode
companion object {
private val LANGUAGE_TO_METADATA_VERSION = EnumMap<LanguageVersion, JvmMetadataVersion>(LanguageVersion::class.java).apply {
val oldMetadataVersion = JvmMetadataVersion(1, 1, 18)
this[KOTLIN_1_0] = oldMetadataVersion
this[KOTLIN_1_1] = oldMetadataVersion
this[KOTLIN_1_2] = oldMetadataVersion
this[KOTLIN_1_3] = oldMetadataVersion
this[KOTLIN_1_4] = JvmMetadataVersion(1, 4, 3)
this[KOTLIN_1_5] = JvmMetadataVersion.INSTANCE
this[KOTLIN_1_6] = JvmMetadataVersion(1, 6, 0)
check(size == LanguageVersion.values().size) {
"Please add mappings from the missing LanguageVersion instances to the corresponding JvmMetadataVersion " +
"in `GenerationState.LANGUAGE_TO_METADATA_VERSION`"
}
}
}
}
private val doNotGenerateInLightClassMode = setOf(CLASS_MEMBER_DELEGATION_TO_DEFAULT_IMPL, BRIDGE, COLLECTION_STUB, AUGMENTED_BUILTIN_API)
@@ -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.5.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.5.0, expected version is $ABI_VERSION$.
$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.6.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.6.0, expected version is $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.5.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 binary version of its metadata is 1.6.0, expected version is $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.5.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 binary version of its metadata is 1.6.0, expected version is $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.5.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 binary version of its metadata is 1.6.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library.jar!/a/C.class
c.let { C() }
^
@@ -421,22 +421,38 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
}
fun testStrictMetadataVersionSemanticsOldVersion() {
val nextMetadataVersion = JvmMetadataVersion(JvmMetadataVersion.INSTANCE.major, JvmMetadataVersion.INSTANCE.minor + 1, 0)
val library = compileLibrary(
"library", additionalOptions = listOf("-Xgenerate-strict-metadata-version", "-Xmetadata-version=1.5.0")
"library", additionalOptions = listOf("-Xgenerate-strict-metadata-version", "-Xmetadata-version=$nextMetadataVersion")
)
compileKotlin("source.kt", tmpdir, listOf(library))
}
fun testMetadataVersionDerivedFromLanguage() {
compileKotlin("source.kt", tmpdir, additionalOptions = listOf("-language-version", "1.3"), expectedFileName = null)
for (languageVersion in LanguageVersion.values()) {
if (languageVersion.isUnsupported) continue
val expectedVersion = JvmMetadataVersion(1, 1, 18)
val topLevelClass = LocalFileKotlinClass.create(File(tmpdir.absolutePath, "Foo.class"))!!
assertEquals(expectedVersion, topLevelClass.classHeader.metadataVersion)
compileKotlin(
"source.kt", tmpdir, additionalOptions = listOf("-language-version", languageVersion.versionString),
expectedFileName = null
)
val moduleFile = File(tmpdir.absolutePath, "META-INF/main.kotlin_module").readBytes()
val versionNumber = ModuleMapping.readVersionNumber(DataInputStream(ByteArrayInputStream(moduleFile)))!!
assertEquals(expectedVersion, JvmMetadataVersion(*versionNumber))
// Starting from Kotlin 1.4, major.minor version of JVM metadata must be equal to the language version.
// From Kotlin 1.0 to 1.4, we used JVM metadata version 1.1.*.
val expectedMajor = 1
val expectedMinor = if (languageVersion < LanguageVersion.KOTLIN_1_4) 1 else languageVersion.minor
val topLevelClass = LocalFileKotlinClass.create(File(tmpdir.absolutePath, "Foo.class"))!!
val classVersion = topLevelClass.classHeader.metadataVersion
assertEquals("Actual version: $classVersion", expectedMajor, classVersion.major)
assertEquals("Actual version: $classVersion", expectedMinor, classVersion.minor)
val moduleFile = File(tmpdir.absolutePath, "META-INF/main.kotlin_module").readBytes()
val versionNumber = ModuleMapping.readVersionNumber(DataInputStream(ByteArrayInputStream(moduleFile)))!!
val moduleVersion = JvmMetadataVersion(*versionNumber)
assertEquals("Actual version: $moduleVersion", expectedMajor, moduleVersion.major)
assertEquals("Actual version: $moduleVersion", expectedMinor, moduleVersion.minor)
}
}
/*test source mapping generation when source info is absent*/
@@ -26,7 +26,7 @@ class JvmMetadataVersion(versionArray: IntArray, val isStrictSemantics: Boolean)
companion object {
@JvmField
val INSTANCE = JvmMetadataVersion(1, 4, 2)
val INSTANCE = JvmMetadataVersion(1, 5, 0)
@JvmField
val INVALID_VERSION = JvmMetadataVersion()
+1 -1
View File
@@ -11,7 +11,7 @@ description = "Kotlin Full Reflection Library"
buildscript {
dependencies {
classpath("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.1.0")
classpath("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.2.0")
}
}
@@ -6,6 +6,11 @@ configurations {
}
dependencies {
// Override dependency of binary-compatibility-validator:0.2.3 on kotlinx-metadata-jvm:0.1.0,
// until the new version of the binary compatibility validator is released.
// kotlinx-metadata-jvm 0.1.0 can't read metadata of version 1.5 and greater.
runtimeOnly("org.jetbrains.kotlinx:kotlinx-metadata-jvm:0.2.0")
compile("org.jetbrains.kotlinx:binary-compatibility-validator:0.2.3")
testCompile project(':kotlin-test:kotlin-test-junit')