Add -Xskip-prerelease-check compiler argument

#KT-38070 Fixed
This commit is contained in:
Alexander Udalov
2020-05-01 19:20:46 +02:00
parent 37e676a4a6
commit a0400f59c2
23 changed files with 142 additions and 13 deletions

View File

@@ -89,10 +89,13 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
@Argument(
value = "-Xskip-metadata-version-check",
description = "Load classes with bad metadata version anyway (incl. pre-release classes)"
description = "Allow to load classes with bad metadata version and pre-release classes"
)
var skipMetadataVersionCheck: Boolean by FreezableVar(false)
@Argument(value = "-Xskip-prerelease-check", description = "Allow to load pre-release classes")
var skipPrereleaseCheck: Boolean by FreezableVar(false)
@Argument(
value = "-Xallow-kotlin-package",
description = "Allow compiling code in package 'kotlin' and allow not requiring kotlin.stdlib in module-info"
@@ -340,6 +343,7 @@ abstract class CommonCompilerArguments : CommonToolArguments() {
open fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> {
return HashMap<AnalysisFlag<*>, Any>().apply {
put(AnalysisFlags.skipMetadataVersionCheck, skipMetadataVersionCheck)
put(AnalysisFlags.skipPrereleaseCheck, skipPrereleaseCheck || skipMetadataVersionCheck)
put(AnalysisFlags.multiPlatformDoNotCheckActual, noCheckActual)
val experimentalFqNames = experimental?.toList().orEmpty()
if (experimentalFqNames.isNotEmpty()) {

View File

@@ -166,7 +166,7 @@ class AnalyzerWithCompilerReport(
fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean {
val hasErrors = reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector))
if (diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS || it.factory == Errors.PRE_RELEASE_CLASS }) {
if (diagnostics.any { it.factory == Errors.INCOMPATIBLE_CLASS }) {
messageCollector.report(
ERROR,
"Incompatible classes were found in dependencies. " +
@@ -174,6 +174,15 @@ class AnalyzerWithCompilerReport(
)
}
if (diagnostics.any { it.factory == Errors.PRE_RELEASE_CLASS }) {
messageCollector.report(
ERROR,
"Pre-release classes were found in dependencies. " +
"Remove them from the classpath, recompile with a release compiler " +
"or use '-Xskip-prerelease-check' to suppress errors"
)
}
if (diagnostics.any { it.factory == Errors.IR_COMPILED_CLASS }) {
messageCollector.report(
ERROR,

View File

@@ -9,6 +9,9 @@ object AnalysisFlags {
@JvmStatic
val skipMetadataVersionCheck by AnalysisFlag.Delegates.Boolean
@JvmStatic
val skipPrereleaseCheck by AnalysisFlag.Delegates.Boolean
@JvmStatic
val multiPlatformDoNotCheckActual by AnalysisFlag.Delegates.Boolean

View File

@@ -14,8 +14,10 @@ import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfigu
class CompilerDeserializationConfiguration(languageVersionSettings: LanguageVersionSettings) : DeserializationConfiguration {
override val skipMetadataVersionCheck = languageVersionSettings.getFlag(AnalysisFlags.skipMetadataVersionCheck)
override val skipPrereleaseCheck = languageVersionSettings.getFlag(AnalysisFlags.skipPrereleaseCheck)
override val reportErrorsOnPreReleaseDependencies =
!skipMetadataVersionCheck && !languageVersionSettings.isPreRelease() && !KotlinCompilerVersion.isPreRelease()
!skipPrereleaseCheck && !languageVersionSettings.isPreRelease() && !KotlinCompilerVersion.isPreRelease()
override val reportErrorsOnIrDependencies = languageVersionSettings.getFlag(AnalysisFlags.reportErrorsOnIrDependencies)

View File

@@ -62,7 +62,8 @@ where advanced options include:
-Xread-deserialized-contracts Enable reading of contracts from metadata
-Xreport-output-files Report source to output files mapping
-Xreport-perf Report detailed performance statistics
-Xskip-metadata-version-check Load classes with bad metadata version anyway (incl. pre-release classes)
-Xskip-metadata-version-check Allow to load classes with bad metadata version and pre-release classes
-Xskip-prerelease-check Allow to load pre-release classes
-Xuse-experimental=<fq.name> Enable, but don't propagate usages of experimental API for marker annotation with the given fully qualified name
-Xuse-fir Compile using Front-end IR. Warning: this feature is far from being production-ready
-Xuse-mixed-named-arguments Enable Support named arguments in their own position even if the result appears as mixed

View File

@@ -140,7 +140,8 @@ where advanced options include:
-Xread-deserialized-contracts Enable reading of contracts from metadata
-Xreport-output-files Report source to output files mapping
-Xreport-perf Report detailed performance statistics
-Xskip-metadata-version-check Load classes with bad metadata version anyway (incl. pre-release classes)
-Xskip-metadata-version-check Allow to load classes with bad metadata version and pre-release classes
-Xskip-prerelease-check Allow to load pre-release classes
-Xuse-experimental=<fq.name> Enable, but don't propagate usages of experimental API for marker annotation with the given fully qualified name
-Xuse-fir Compile using Front-end IR. Warning: this feature is far from being production-ready
-Xuse-mixed-named-arguments Enable Support named arguments in their own position even if the result appears as mixed

View File

@@ -1,4 +1,4 @@
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
error: pre-release classes were found in dependencies. Remove them from the classpath, recompile with a release compiler or use '-Xskip-prerelease-check' to suppress errors
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/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, nested: A.Nested) {
^

View File

@@ -1,4 +1,4 @@
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
error: pre-release classes were found in dependencies. Remove them from the classpath, recompile with a release compiler or use '-Xskip-prerelease-check' to suppress errors
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:5:16: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
fun baz(param: A, nested: A.Nested) {
^
@@ -38,4 +38,4 @@ compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreRe
compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibraryJs/source.kt:14:12: error: package 'a' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler
val z: TA = ""
^
COMPILATION_ERROR
COMPILATION_ERROR

View File

@@ -0,0 +1,9 @@
package a
open class A {
class Nested
}
fun foo() {}
var bar = 42
typealias TA = String

View File

@@ -0,0 +1,15 @@
@file:Suppress("UNUSED_VARIABLE")
package usage
import a.*
fun baz(param: A) {
val constructor = A()
val methodCall = param.hashCode()
val supertype = object : A() {}
val x = foo()
val y = bar
bar = 239
val z: TA = ""
}

View File

@@ -0,0 +1,11 @@
package a
open class A {
class Nested
fun method() {}
}
fun foo() {}
var bar = 42
typealias TA = String

View File

@@ -0,0 +1,47 @@
error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors
$TMP_DIR$/library-after.jar!/META-INF/main.kotlin_module: error: module was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:16: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
fun baz(param: A, nested: A.Nested) {
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:27: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
fun baz(param: A, nested: A.Nested) {
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:5:29: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class
fun baz(param: A, nested: A.Nested) {
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:6:23: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
val constructor = A()
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:18: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
val nested = A.Nested()
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:7:20: error: class 'a.A.Nested' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A$Nested.class
val nested = A.Nested()
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:8:22: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
val methodCall = param.method()
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:9:30: error: class 'a.A' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 42.0.0, expected version is $ABI_VERSION$.
The class is loaded from $TMP_DIR$/library-after.jar!/a/A.class
val supertype = object : A() {}
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:11:13: error: unresolved reference: foo
val x = foo()
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:12:13: error: unresolved reference: bar
val y = bar
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:13:5: error: unresolved reference: bar
bar = 239
^
compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersionSkipPrereleaseCheckHasNoEffect/source.kt:14:12: error: unresolved reference: TA
val z: TA = ""
^
COMPILATION_ERROR

View File

@@ -0,0 +1,15 @@
package usage
import a.*
fun baz(param: A, nested: A.Nested) {
val constructor = A()
val nested = A.Nested()
val methodCall = param.method()
val supertype = object : A() {}
val x = foo()
val y = bar
bar = 239
val z: TA = ""
}

View File

@@ -295,12 +295,16 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestPreReleaseKotlinLibrary(K2JSCompiler(), "library", File(tmpdir, "usage.js"))
}
fun testReleaseCompilerAgainstPreReleaseLibrarySkipVersionCheck() {
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir, "-Xskip-metadata-version-check")
fun testReleaseCompilerAgainstPreReleaseLibrarySkipPrereleaseCheck() {
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir, "-Xskip-prerelease-check")
}
fun testReleaseCompilerAgainstPreReleaseLibraryJsSkipVersionCheck() {
doTestPreReleaseKotlinLibrary(K2JSCompiler(), "library", File(tmpdir, "usage.js"), "-Xskip-metadata-version-check")
fun testReleaseCompilerAgainstPreReleaseLibraryJsSkipPrereleaseCheck() {
doTestPreReleaseKotlinLibrary(K2JSCompiler(), "library", File(tmpdir, "usage.js"), "-Xskip-prerelease-check")
}
fun testReleaseCompilerAgainstPreReleaseLibrarySkipMetadataVersionCheck() {
doTestPreReleaseKotlinLibrary(K2JVMCompiler(), "library", tmpdir, "-Xskip-metadata-version-check")
}
fun testPreReleaseCompilerAgainstPreReleaseLibraryStableLanguageVersion() {
@@ -362,6 +366,10 @@ class CompileKotlinAgainstCustomBinariesTest : AbstractKotlinCompilerIntegration
doTestKotlinLibraryWithWrongMetadataVersionJs("library", "-Xskip-metadata-version-check")
}
fun testWrongMetadataVersionSkipPrereleaseCheckHasNoEffect() {
doTestKotlinLibraryWithWrongMetadataVersion("library", null, "-Xskip-prerelease-check")
}
fun testRequireKotlin() {
compileKotlin("source.kt", tmpdir, listOf(compileLibrary("library")))
}

View File

@@ -94,7 +94,7 @@ class DeserializedDescriptorResolver {
// We report pre-release errors on .class files produced by 1.3-M1 even if this compiler is pre-release. This is needed because
// 1.3-M1 did not mangle names of functions mentioning inline classes yet, and we don't want to support this case in the codegen
private val KotlinJvmBinaryClass.isCompiledWith13M1: Boolean
get() = !components.configuration.skipMetadataVersionCheck &&
get() = !components.configuration.skipPrereleaseCheck &&
classHeader.isPreRelease && classHeader.metadataVersion == KOTLIN_1_3_M1_METADATA_VERSION
private val KotlinJvmBinaryClass.isInvisibleJvmIrDependency: Boolean

View File

@@ -9,6 +9,9 @@ interface DeserializationConfiguration {
val skipMetadataVersionCheck: Boolean
get() = false
val skipPrereleaseCheck: Boolean
get() = false
val reportErrorsOnPreReleaseDependencies: Boolean
get() = false