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) val consistency = checkCompilerClasspathConsistency(messageCollector, apiVersion, runtimeJarsInfo)
if (consistency != ClasspathConsistency.Consistent) { if (consistency != ClasspathConsistency.Consistent) {
val extraHint = val message = when (consistency) {
if (consistency == ClasspathConsistency.InconsistentWithApiVersion) is ClasspathConsistency.InconsistentWithApiVersion ->
"Remove them from the classpath or pass the correct '-api-version' explicitly. " + "Runtime JAR files in the classpath have the version ${consistency.actualRuntimeVersion}, " +
"You can also pass the '-language-version' instead, which will restrict not only the APIs " + "which is older than the API version $apiVersion. " +
"to the specified version, but also the language features. " + "Remove them from the classpath or pass '-api-version ${consistency.actualRuntimeVersion}' explicitly. " +
"Alternatively, you can use '-Xskip-runtime-version-check' to suppress this error" "You can also pass '-language-version ${consistency.actualRuntimeVersion}' instead, which will restrict " +
else "not only the APIs to the specified version, but also the language features. " +
"Remove them from the classpath or use '-Xskip-runtime-version-check' to suppress errors" "Alternatively, you can use '-Xskip-runtime-version-check' to suppress this error"
messageCollector.issue(null, "Some runtime JAR files in the classpath have an incompatible version. $extraHint") 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 val librariesWithBundled = runtimeJarsInfo.otherLibrariesWithBundledRuntime
@@ -158,7 +162,7 @@ object JvmRuntimeVersionsConsistencyChecker {
private sealed class ClasspathConsistency { private sealed class ClasspathConsistency {
object Consistent : ClasspathConsistency() object Consistent : ClasspathConsistency()
object InconsistentWithApiVersion : ClasspathConsistency() class InconsistentWithApiVersion(val actualRuntimeVersion: MavenComparableVersion) : ClasspathConsistency()
object InconsistentWithCompilerVersion : ClasspathConsistency() object InconsistentWithCompilerVersion : ClasspathConsistency()
object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency() object InconsistentBecauseOfRuntimesWithDifferentVersions : ClasspathConsistency()
} }
@@ -176,13 +180,15 @@ object JvmRuntimeVersionsConsistencyChecker {
checkNotNewerThanCompiler(messageCollector, it) checkNotNewerThanCompiler(messageCollector, it)
}.any { it }) return ClasspathConsistency.InconsistentWithCompilerVersion }.any { it }) return ClasspathConsistency.InconsistentWithCompilerVersion
if (checkMatchingVersions(messageCollector, runtimeJarsInfo)) { val jars = runtimeJarsInfo.jars
return ClasspathConsistency.InconsistentBecauseOfRuntimesWithDifferentVersions 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) checkCompatibleWithApiVersion(messageCollector, it, apiVersion)
}.any { it }) return ClasspathConsistency.InconsistentWithApiVersion }.any { it }) return ClasspathConsistency.InconsistentWithApiVersion(runtimeVersion)
return ClasspathConsistency.Consistent return ClasspathConsistency.Consistent
} }
@@ -205,21 +211,26 @@ object JvmRuntimeVersionsConsistencyChecker {
return false return false
} }
private fun checkMatchingVersions(messageCollector: MessageCollector, runtimeJarsInfo: RuntimeJarsInfo): Boolean { // Returns the version if it's the same across all jars, or null if versions of some jars differ.
val oldestJar = runtimeJarsInfo.jars.minBy { it.version } ?: return false private fun checkMatchingVersionsAndGetRuntimeVersion(
val newestJar = runtimeJarsInfo.jars.maxBy { it.version } ?: return false 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) { // If the oldest version is the same as the newest version, then all jars have the same version
messageCollector.issue(null, buildString { if (oldestVersion == newestVersion) return oldestVersion
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
}
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) { private fun MessageCollector.issue(file: VirtualFile?, message: String, severity: CompilerMessageSeverity = VERSION_ISSUE_SEVERITY) {