Report pre-release errors if release LV is used

#KT-21267 Fixed
This commit is contained in:
Alexander Udalov
2017-11-15 12:50:23 +01:00
parent 64a8008a8a
commit d386712903
15 changed files with 80 additions and 26 deletions
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.config.ApiVersion
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.config.shouldWritePreReleaseFlag
import org.jetbrains.kotlin.config.isPreRelease
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
@@ -63,7 +63,7 @@ fun JvmBuildMetaInfo(args: CommonCompilerArguments): JvmBuildMetaInfo {
val languageVersion = args.languageVersion?.let((LanguageVersion)::fromVersionString) ?: LanguageVersion.LATEST_STABLE
return JvmBuildMetaInfo(
isEAP = languageVersion.shouldWritePreReleaseFlag(),
isEAP = languageVersion.isPreRelease(),
compilerBuildVersion = KotlinCompilerVersion.VERSION,
languageVersionString = languageVersion.versionString,
apiVersionString = args.apiVersion ?: ApiVersion.LATEST_STABLE.versionString,
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.codegen
import org.jetbrains.kotlin.codegen.state.GenerationState
import org.jetbrains.kotlin.config.shouldWritePreReleaseFlag
import org.jetbrains.kotlin.config.isPreRelease
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
@@ -36,7 +36,7 @@ fun writeKotlinMetadata(
av.visit(JvmAnnotationNames.BYTECODE_VERSION_FIELD_NAME, JvmBytecodeBinaryVersion.INSTANCE.toArray())
av.visit(JvmAnnotationNames.KIND_FIELD_NAME, kind.id)
var flags = extraFlags
if (state.languageVersionSettings.shouldWritePreReleaseFlag()) {
if (state.languageVersionSettings.isPreRelease()) {
flags = flags or JvmAnnotationNames.METADATA_PRE_RELEASE_FLAG
}
if (flags != 0) {
@@ -19,12 +19,13 @@ package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.config.AnalysisFlag
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 skipPreReleaseCheck = skipMetadataVersionCheck || !languageVersionSettings.languageVersion.isStable
override val reportErrorsOnPreReleaseDependencies = !skipMetadataVersionCheck && !languageVersionSettings.isPreRelease()
override val typeAliasesAllowed = languageVersionSettings.supportsFeature(LanguageFeature.TypeAliases)
@@ -0,0 +1,5 @@
package a
class A
fun A.foo() = ""
@@ -0,0 +1,7 @@
package usage
import a.*
fun baz(param: A) {
param.foo()
}
@@ -0,0 +1,8 @@
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/source.kt:5:16: error: class 'a.A' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
fun baz(param: A) {
^
compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/source.kt:6:5: error: class 'a.AKt' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
foo()
^
COMPILATION_ERROR
@@ -0,0 +1,7 @@
package usage
import a.*
fun baz(param: A) {
foo()
}
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.codegen.inline.remove
import org.jetbrains.kotlin.codegen.optimization.common.asSequence
import org.jetbrains.kotlin.codegen.optimization.common.intConstant
import org.jetbrains.kotlin.config.KotlinCompilerVersion.TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY
import org.jetbrains.kotlin.config.LanguageVersion
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
@@ -131,27 +132,28 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
) {
// Compiles the library with the "pre-release" flag, then compiles a usage of this library in the release mode
val result = try {
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "true")
val result = withPreRelease(true) {
when (compiler) {
is K2JSCompiler -> compileJsLibrary(libraryName)
is K2JVMCompiler -> compileLibrary(libraryName)
else -> throw UnsupportedOperationException(compiler.toString())
}
}
finally {
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY)
}
try {
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, "false")
withPreRelease(false) {
compileKotlin("source.kt", usageDestination, listOf(result), compiler, additionalOptions.toList())
}
finally {
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY)
}
}
private fun <T> withPreRelease(value: Boolean, block: () -> T): T =
try {
System.setProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY, value.toString())
block()
}
finally {
System.clearProperty(TEST_IS_PRE_RELEASE_SYSTEM_PROPERTY)
}
// ------------------------------------------------------------------------------
fun testRawTypes() {
@@ -258,6 +260,23 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestPreReleaseKotlinLibrary(K2JSCompiler(), "library", File(tmpdir, "usage.js"), "-Xskip-metadata-version-check")
}
fun testPreReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion() {
withPreRelease(true) {
val library = compileLibrary("library")
val someStableReleasedVersion = LanguageVersion.values().first().also { assert(it.isStable) }
compileKotlin("source.kt", tmpdir, listOf(library), K2JVMCompiler(),
listOf("-language-version", someStableReleasedVersion.versionString))
}
}
fun testPreReleaseCompilerAgainstPreReleaseLibraryLatestStable() {
withPreRelease(true) {
val library = compileLibrary("library")
compileKotlin("source.kt", tmpdir, listOf(library), K2JVMCompiler(),
listOf("-language-version", LanguageVersion.LATEST_STABLE.versionString))
}
}
fun testWrongMetadataVersion() {
doTestKotlinLibraryWithWrongMetadataVersion("library", null)
}
@@ -189,10 +189,10 @@ class LanguageVersionSettingsImpl @JvmOverloads constructor(
}
}
fun LanguageVersionSettings.shouldWritePreReleaseFlag(): Boolean =
languageVersion.shouldWritePreReleaseFlag()
fun LanguageVersionSettings.isPreRelease(): Boolean =
languageVersion.isPreRelease()
fun LanguageVersion.shouldWritePreReleaseFlag(): Boolean {
fun LanguageVersion.isPreRelease(): Boolean {
if (!isStable) return true
return KotlinCompilerVersion.isPreRelease() && this == LanguageVersion.LATEST_STABLE
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.load.kotlin
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
@@ -75,9 +74,12 @@ class DeserializedDescriptorResolver {
return IncompatibleVersionErrorData(classHeader.metadataVersion, JvmMetadataVersion.INSTANCE, location, classId)
}
/**
* @return true if the class is invisible because it's compiled by a pre-release compiler, and this compiler is either released
* or is run with a released language version.
*/
private val KotlinJvmBinaryClass.isPreReleaseInvisible: Boolean
get() = !components.configuration.skipPreReleaseCheck &&
!KotlinCompilerVersion.isPreRelease() &&
get() = components.configuration.reportErrorsOnPreReleaseDependencies &&
(classHeader.isPreRelease || classHeader.metadataVersion == KOTLIN_1_1_EAP_METADATA_VERSION)
internal fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? {
@@ -20,7 +20,7 @@ interface DeserializationConfiguration {
val skipMetadataVersionCheck: Boolean
get() = false
val skipPreReleaseCheck: Boolean
val reportErrorsOnPreReleaseDependencies: Boolean
get() = false
val typeAliasesAllowed: Boolean
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.serialization.js
import org.jetbrains.kotlin.config.KotlinCompilerVersion
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
@@ -80,7 +79,7 @@ class KotlinJavascriptPackageFragment(
get() = null
override val isPreReleaseInvisible: Boolean =
!configuration.skipPreReleaseCheck && (header.flags and 1) != 0 && !KotlinCompilerVersion.isPreRelease()
configuration.reportErrorsOnPreReleaseDependencies && (header.flags and 1) != 0
override val presentableString: String
get() = "Package '$fqName'"
@@ -17,7 +17,7 @@
package org.jetbrains.kotlin.serialization.js
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.shouldWritePreReleaseFlag
import org.jetbrains.kotlin.config.isPreRelease
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.name.FqName
@@ -243,7 +243,7 @@ object KotlinJavascriptSerializationUtil {
header.packageFqName = packageFqName.asString()
}
if (languageVersionSettings.shouldWritePreReleaseFlag()) {
if (languageVersionSettings.isPreRelease()) {
header.flags = 1
}