From 475a80b6411ca2def50c5c4d84de9ec8af98abb1 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 23 Aug 2018 16:46:26 +0200 Subject: [PATCH] Do not write pre-release binaries for stable LV This commit reverts f6571effcc03a3c1b45c85a470d5b5ab36413f5b and reimplements the desired logic in another way. In particular, we'd like these two conditions to hold: 1) only the release compiler with stable language settings (meaning, language version is a released version of Kotlin and no experimental features are enabled) should report errors when _reading_ pre-release binaries. 2) the compiler should _write_ pre-release binaries only if language settings are not stable, independent of whether the compiler itself is release or not. From these conditions it follows that we must use different logic to determine how to behave when reading/writing pre-release binaries. Namely, reading (in CompilerDeserializationConfiguration) now checks if both the compiler is release and the language settings are stable, and writing (in LanguageVersionSettings.isPreRelease) checks only that the language settings are stable --- .../CompilerDeserializationConfiguration.kt | 5 ++-- .../CompileKotlinAgainstCustomBinariesTest.kt | 26 +++++++++++++++++++ .../kotlin/config/LanguageVersionSettings.kt | 2 +- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt index d824431d53a..8c3701756d4 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt @@ -6,15 +6,16 @@ package org.jetbrains.kotlin.resolve import org.jetbrains.kotlin.config.AnalysisFlag +import org.jetbrains.kotlin.config.KotlinCompilerVersion import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageVersionSettings -import org.jetbrains.kotlin.config.isPreRelease import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration class CompilerDeserializationConfiguration(languageVersionSettings: LanguageVersionSettings) : DeserializationConfiguration { override val skipMetadataVersionCheck = languageVersionSettings.getFlag(AnalysisFlag.skipMetadataVersionCheck) - override val reportErrorsOnPreReleaseDependencies = !skipMetadataVersionCheck && !languageVersionSettings.isPreRelease() + override val reportErrorsOnPreReleaseDependencies = + !skipMetadataVersionCheck && !languageVersionSettings.isPreRelease() && !KotlinCompilerVersion.isPreRelease() override val typeAliasesAllowed = languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases) diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index ad18c069b03..69335cbc7c3 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.jvm.compiler import com.intellij.openapi.util.io.FileUtil +import junit.framework.TestCase import org.jetbrains.kotlin.cli.WrongBytecodeVersionTest import org.jetbrains.kotlin.cli.common.CLICompiler import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport @@ -255,6 +256,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration "source.kt", tmpdir, listOf(library), K2JVMCompiler(), listOf("-language-version", someStableReleasedVersion.versionString) ) + + checkPreReleaseness(File(tmpdir, "usage/SourceKt.class"), shouldBePreRelease = false) } } @@ -265,6 +268,8 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration "source.kt", tmpdir, listOf(library), K2JVMCompiler(), listOf("-language-version", LanguageVersion.LATEST_STABLE.versionString) ) + + checkPreReleaseness(File(tmpdir, "usage/SourceKt.class"), shouldBePreRelease = true) } } @@ -606,5 +611,26 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration return outputFile } + + private fun checkPreReleaseness(file: File, shouldBePreRelease: Boolean) { + // If there's no "xi" field in the Metadata annotation, it's value is assumed to be 0, i.e. _not_ pre-release + var isPreRelease = false + + ClassReader(file.readBytes()).accept(object : ClassVisitor(Opcodes.ASM6) { + override fun visitAnnotation(desc: String, visible: Boolean): AnnotationVisitor? { + if (desc != JvmAnnotationNames.METADATA_DESC) return null + + return object : AnnotationVisitor(Opcodes.ASM6) { + override fun visit(name: String, value: Any) { + if (name != JvmAnnotationNames.METADATA_EXTRA_INT_FIELD_NAME) return + + isPreRelease = (value as Int and JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG) != 0 + } + } + } + }, 0) + + TestCase.assertEquals("Pre-release flag of the class file has incorrect value", shouldBePreRelease, isPreRelease) + } } } diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 1cdf1189cc6..d6e8406703b 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -271,7 +271,7 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor( } } - override fun isPreRelease(): Boolean = KotlinCompilerVersion.isPreRelease() || + override fun isPreRelease(): Boolean = languageVersion.isPreRelease() || specificFeatures.any { (feature, state) -> state == LanguageFeature.State.ENABLED && feature.forcesPreReleaseBinariesIfEnabled() }