Do not write pre-release binaries for stable LV

This commit reverts f6571effcc 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
This commit is contained in:
Alexander Udalov
2018-08-23 16:46:26 +02:00
parent 053a4b714c
commit 475a80b641
3 changed files with 30 additions and 3 deletions
@@ -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)
@@ -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)
}
}
}
@@ -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()
}