Refactor API version inference/checking code

The behavior is not changed in this commit
This commit is contained in:
Alexander Udalov
2018-02-09 18:15:35 +01:00
parent 749773aa36
commit 3f6aeb6dca
@@ -102,33 +102,38 @@ object JvmRuntimeVersionsConsistencyChecker {
if (runtimeJarsInfo.jars.isEmpty()) return
val languageVersionSettings = configuration.languageVersionSettings
val apiVersion = languageVersionSettings.apiVersion.version
val currentApi = languageVersionSettings.apiVersion
val consistency = checkCompilerClasspathConsistency(messageCollector, apiVersion, runtimeJarsInfo)
val consistency = checkCompilerClasspathConsistency(messageCollector, currentApi.version, runtimeJarsInfo)
if (consistency is ClasspathConsistency.InconsistentWithApiVersion) {
val actualRuntimeVersion = consistency.actualRuntimeVersion
messageCollector.issue(
null,
"Runtime JAR files in the classpath have the version $actualRuntimeVersion, " +
"which is older than the API version $apiVersion. " +
"Consider using the runtime of version $apiVersion, or pass '-api-version $actualRuntimeVersion' explicitly to " +
"restrict the available APIs to the runtime of version $actualRuntimeVersion. " +
"which is older than the API version ${currentApi.version}. " +
"Consider using the runtime of version ${currentApi.version}, or pass '-api-version $actualRuntimeVersion' " +
"explicitly to restrict the available APIs to the runtime of version $actualRuntimeVersion. " +
"You can also pass '-language-version $actualRuntimeVersion' instead, which will restrict " +
"not only the APIs to the specified version, but also the language features"
)
val actualApi = ApiVersion.parse(actualRuntimeVersion.toString())
if (actualApi != null) {
val inferredApiVersion =
if (configuration.getBoolean(CLIConfigurationKeys.IS_API_VERSION_EXPLICIT))
languageVersionSettings.apiVersion
else
// "minOf" is needed in case when API version was inferred from language version and it's older than actualApi.
// For example, in "kotlinc-1.2 -language-version 1.0 -cp kotlin-runtime-1.1.jar" we should still infer API = 1.0
minOf(languageVersionSettings.apiVersion, actualApi)
for (jar in consistency.incompatibleJars) {
messageCollector.issue(
jar.file,
"Runtime JAR file has version ${jar.version} which is older than required for API version ${currentApi.version}"
)
}
val actualApi = ApiVersion.parse(actualRuntimeVersion.toString())
if (actualApi == null) {
messageCollector.issue(null, "Could not parse runtime JAR version: $actualRuntimeVersion")
} else if (!configuration.getBoolean(CLIConfigurationKeys.IS_API_VERSION_EXPLICIT) && actualApi < currentApi) {
// If there's no explicit "-api-version" AND there's an old stdlib in the classpath (older than the default value of API),
// we infer API = the version of that stdlib.
// Note that "no explicit -api-version" requirement is necessary because for example, in
// "kotlinc-1.2 -language-version 1.0 -cp kotlin-runtime-1.1.jar" we should still infer API = 1.0
val newSettings = object : LanguageVersionSettings by languageVersionSettings {
override val apiVersion: ApiVersion get() = inferredApiVersion
override val apiVersion: ApiVersion get() = actualApi
}
messageCollector.issue(null, "Old runtime has been found in the classpath. " +
@@ -137,9 +142,6 @@ object JvmRuntimeVersionsConsistencyChecker {
configuration.languageVersionSettings = newSettings
}
else {
messageCollector.issue(null, "Could not parse runtime JAR version: $actualRuntimeVersion")
}
}
else if (consistency != ClasspathConsistency.Consistent) {
messageCollector.issue(
@@ -165,7 +167,10 @@ object JvmRuntimeVersionsConsistencyChecker {
private sealed class ClasspathConsistency {
object Consistent : ClasspathConsistency()
class InconsistentWithApiVersion(val actualRuntimeVersion: MavenComparableVersion) : ClasspathConsistency()
class InconsistentWithApiVersion(
val actualRuntimeVersion: MavenComparableVersion,
val incompatibleJars: List<KotlinLibraryFile>
) : ClasspathConsistency()
object InconsistentWithCompilerVersion : ClasspathConsistency()
object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency()
}
@@ -189,9 +194,10 @@ object JvmRuntimeVersionsConsistencyChecker {
val runtimeVersion = checkMatchingVersionsAndGetRuntimeVersion(messageCollector, jars)
?: return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions
if (jars.map {
checkCompatibleWithApiVersion(messageCollector, it, apiVersion)
}.any { it }) return ClasspathConsistency.InconsistentWithApiVersion(runtimeVersion)
val jarsIncompatibleWithApiVersion = jars.filter { it.version < apiVersion }
if (jarsIncompatibleWithApiVersion.isNotEmpty()) {
return ClasspathConsistency.InconsistentWithApiVersion(runtimeVersion, jarsIncompatibleWithApiVersion)
}
return ClasspathConsistency.Consistent
}
@@ -208,19 +214,6 @@ object JvmRuntimeVersionsConsistencyChecker {
return false
}
private fun checkCompatibleWithApiVersion(
messageCollector: MessageCollector, jar: KotlinLibraryFile, apiVersion: MavenComparableVersion
): Boolean {
if (jar.version < apiVersion) {
messageCollector.issue(
jar.file,
"Runtime JAR file has version ${jar.version} which is older than required for API version $apiVersion"
)
return true
}
return false
}
// Returns the version if it's the same across all jars, or null if versions of some jars differ.
private fun checkMatchingVersionsAndGetRuntimeVersion(
messageCollector: MessageCollector,