Improve error on runtime of version different than API version

Include the actual runtime version in the error message
This commit is contained in:
Alexander Udalov
2017-02-03 15:50:38 +03:00
parent 57f8ef372f
commit ca1ed850b8
@@ -125,15 +125,19 @@ object JvmRuntimeVersionsConsistencyChecker {
val consistency = checkCompilerClasspathConsistency(messageCollector, apiVersion, runtimeJarsInfo)
if (consistency != ClasspathConsistency.Consistent) {
val extraHint =
if (consistency == ClasspathConsistency.InconsistentWithApiVersion)
"Remove them from the classpath or pass the correct '-api-version' explicitly. " +
"You can also pass the '-language-version' instead, which will restrict not only the APIs " +
"to the specified version, but also the language features. " +
"Alternatively, you can use '-Xskip-runtime-version-check' to suppress this error"
else
"Remove them from the classpath or use '-Xskip-runtime-version-check' to suppress errors"
messageCollector.issue(null, "Some runtime JAR files in the classpath have an incompatible version. $extraHint")
val message = when (consistency) {
is ClasspathConsistency.InconsistentWithApiVersion ->
"Runtime JAR files in the classpath have the version ${consistency.actualRuntimeVersion}, " +
"which is older than the API version $apiVersion. " +
"Remove them from the classpath or pass '-api-version ${consistency.actualRuntimeVersion}' explicitly. " +
"You can also pass '-language-version ${consistency.actualRuntimeVersion}' instead, which will restrict " +
"not only the APIs to the specified version, but also the language features. " +
"Alternatively, you can use '-Xskip-runtime-version-check' to suppress this error"
else ->
"Some runtime JAR files in the classpath have an incompatible version. " +
"Remove them from the classpath or use '-Xskip-runtime-version-check' to suppress errors"
}
messageCollector.issue(null, message)
}
val librariesWithBundled = runtimeJarsInfo.otherLibrariesWithBundledRuntime
@@ -158,7 +162,7 @@ object JvmRuntimeVersionsConsistencyChecker {
private sealed class ClasspathConsistency {
object Consistent : ClasspathConsistency()
object InconsistentWithApiVersion : ClasspathConsistency()
class InconsistentWithApiVersion(val actualRuntimeVersion: MavenComparableVersion) : ClasspathConsistency()
object InconsistentWithCompilerVersion : ClasspathConsistency()
object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency()
}
@@ -176,13 +180,15 @@ object JvmRuntimeVersionsConsistencyChecker {
checkNotNewerThanCompiler(messageCollector, it)
}.any { it }) return ClasspathConsistency.InconsistentWithCompilerVersion
if (checkMatchingVersions(messageCollector, runtimeJarsInfo)) {
return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions
}
val jars = runtimeJarsInfo.jars
if (jars.isEmpty()) return ClasspathConsistency.Consistent
if (runtimeJarsInfo.jars.map {
val runtimeVersion = checkMatchingVersionsAndGetRuntimeVersion(messageCollector, jars)
?: return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions
if (jars.map {
checkCompatibleWithApiVersion(messageCollector, it, apiVersion)
}.any { it }) return ClasspathConsistency.InconsistentWithApiVersion
}.any { it }) return ClasspathConsistency.InconsistentWithApiVersion(runtimeVersion)
return ClasspathConsistency.Consistent
}
@@ -205,21 +211,26 @@ object JvmRuntimeVersionsConsistencyChecker {
return false
}
private fun checkMatchingVersions(messageCollector: MessageCollector, runtimeJarsInfo: RuntimeJarsInfo): Boolean {
val oldestJar = runtimeJarsInfo.jars.minBy { it.version } ?: return false
val newestJar = runtimeJarsInfo.jars.maxBy { it.version } ?: 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,
jars: List<KotlinLibraryFile>
): MavenComparableVersion? {
assert(jars.isNotEmpty()) { "'jars' must not be empty" }
val oldestVersion = jars.minBy { it.version }!!.version
val newestVersion = jars.maxBy { it.version }!!.version
if (oldestJar.version != newestJar.version) {
messageCollector.issue(null, buildString {
appendln("Runtime JAR files in the classpath must have the same version. These files were found in the classpath:")
for (jar in runtimeJarsInfo.jars) {
appendln(" ${jar.file.path} (version ${jar.version})")
}
}.trimEnd())
return true
}
// If the oldest version is the same as the newest version, then all jars have the same version
if (oldestVersion == newestVersion) return oldestVersion
return false
messageCollector.issue(null, buildString {
appendln("Runtime JAR files in the classpath must have the same version. These files were found in the classpath:")
for (jar in jars) {
appendln(" ${jar.file.path} (version ${jar.version})")
}
}.trimEnd())
return null
}
private fun MessageCollector.issue(file: VirtualFile?, message: String, severity: CompilerMessageSeverity = VERSION_ISSUE_SEVERITY) {