diff --git a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt index 66bda40e3d7..3e88492ecba 100644 --- a/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt +++ b/build-common/src/org/jetbrains/kotlin/build/JvmBuildMetaInfo.kt @@ -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, diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt index bd98e557e72..fbc0f56ccd4 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/writeAnnotationUtil.kt @@ -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) { diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt index 654d1080e40..e922d2f22fa 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/CompilerDeserializationConfiguration.kt @@ -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) diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/library/a.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/library/a.kt new file mode 100644 index 00000000000..b1828248591 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/library/a.kt @@ -0,0 +1,5 @@ +package a + +class A + +fun A.foo() = "" diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/output.txt new file mode 100644 index 00000000000..d86bac9de59 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/output.txt @@ -0,0 +1 @@ +OK diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/source.kt new file mode 100644 index 00000000000..298d363e749 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryLatestStable/source.kt @@ -0,0 +1,7 @@ +package usage + +import a.* + +fun baz(param: A) { + param.foo() +} diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/library/a.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/library/a.kt new file mode 100644 index 00000000000..dbf30478826 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/library/a.kt @@ -0,0 +1,5 @@ +package a + +class A + +fun foo() = "" diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/output.txt new file mode 100644 index 00000000000..44ec8ddab78 --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/output.txt @@ -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 diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/source.kt b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/source.kt new file mode 100644 index 00000000000..28999b2eadb --- /dev/null +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/preReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion/source.kt @@ -0,0 +1,7 @@ +package usage + +import a.* + +fun baz(param: A) { + foo() +} diff --git a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt index 28c45dbee28..a4a6f7447d1 100644 --- a/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/jvm/compiler/CompileKotlinAgainstCustomBinariesTest.kt @@ -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 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) } diff --git a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt index 04051bc3917..f859b49da73 100644 --- a/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt +++ b/compiler/util/src/org/jetbrains/kotlin/config/LanguageVersionSettings.kt @@ -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 diff --git a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt index f4a391553b2..274509c740b 100644 --- a/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt +++ b/core/descriptors.jvm/src/org/jetbrains/kotlin/load/kotlin/DeserializedDescriptorResolver.kt @@ -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): Array? { diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt index d85deba9592..2bff1f81d61 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/DeserializationConfiguration.kt @@ -20,7 +20,7 @@ interface DeserializationConfiguration { val skipMetadataVersionCheck: Boolean get() = false - val skipPreReleaseCheck: Boolean + val reportErrorsOnPreReleaseDependencies: Boolean get() = false val typeAliasesAllowed: Boolean diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt index d4aa599a6dd..42473978658 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptPackageFragment.kt @@ -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'" diff --git a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt index 4f402c462aa..c8a4c9622c3 100644 --- a/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt +++ b/js/js.serializer/src/org/jetbrains/kotlin/serialization/js/KotlinJavascriptSerializationUtil.kt @@ -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 }