Improve diagnostics for runtime versions consistency checker
- report the diagnostic on the actual problematic file - output the list of all runtime jars if min version != max version
This commit is contained in:
+8
-7
@@ -28,14 +28,15 @@ data class CompilerMessageLocation private constructor(
|
||||
path + (if (line != -1 || column != -1) " ($line:$column)" else "")
|
||||
|
||||
companion object {
|
||||
@JvmField val NO_LOCATION: CompilerMessageLocation = CompilerMessageLocation(null, -1, -1, null)
|
||||
@JvmField
|
||||
val NO_LOCATION: CompilerMessageLocation = create(null)
|
||||
|
||||
@JvmStatic fun create(
|
||||
path: String?,
|
||||
line: Int,
|
||||
column: Int,
|
||||
lineContent: String?
|
||||
): CompilerMessageLocation =
|
||||
@JvmStatic
|
||||
fun create(path: String?): CompilerMessageLocation =
|
||||
CompilerMessageLocation(path, -1, -1, null)
|
||||
|
||||
@JvmStatic
|
||||
fun create(path: String?, line: Int, column: Int, lineContent: String?): CompilerMessageLocation =
|
||||
if (path == null) NO_LOCATION else CompilerMessageLocation(path, line, column, lineContent)
|
||||
|
||||
private val serialVersionUID: Long = 8228357578L
|
||||
|
||||
+1
-2
@@ -229,9 +229,8 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
|
||||
severity,
|
||||
"Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " +
|
||||
"The binary version of its bytecode is " + data.actualVersion + ", expected version is " + data.expectedVersion,
|
||||
CompilerMessageLocation.create(toSystemDependentName(data.filePath), -1, -1, null)
|
||||
CompilerMessageLocation.create(toSystemDependentName(data.filePath))
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+19
-12
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.cli.jvm
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
@@ -106,9 +107,9 @@ object JvmRuntimeVersionsConsistencyChecker {
|
||||
fun checkCompilerClasspathConsistency(
|
||||
messageCollector: MessageCollector,
|
||||
languageVersionSettings: LanguageVersionSettings?,
|
||||
classpathJars: List<VirtualFile>
|
||||
classpathJarRoots: List<VirtualFile>
|
||||
) {
|
||||
val runtimeJarsInfo = collectRuntimeJarsInfo(classpathJars)
|
||||
val runtimeJarsInfo = collectRuntimeJarsInfo(classpathJarRoots)
|
||||
if (!runtimeJarsInfo.hasAnyJarsToCheck) return
|
||||
|
||||
val languageVersion =
|
||||
@@ -128,13 +129,13 @@ object JvmRuntimeVersionsConsistencyChecker {
|
||||
|
||||
private fun checkNotNewerThanCompiler(messageCollector: MessageCollector, jar: KotlinLibraryFile) {
|
||||
if (jar.version > CURRENT_COMPILER_VERSION) {
|
||||
messageCollector.issue("Run-time JAR file $jar is newer than compiler version $CURRENT_COMPILER_VERSION")
|
||||
messageCollector.issue(jar.file, "Runtime JAR file has version ${jar.version} which is newer than compiler version $CURRENT_COMPILER_VERSION")
|
||||
}
|
||||
}
|
||||
|
||||
private fun checkCompatibleWithLanguageVersion(messageCollector: MessageCollector, jar: KotlinLibraryFile, languageVersion: MavenComparableVersion) {
|
||||
if (jar.version < languageVersion) {
|
||||
messageCollector.issue("Run-time JAR file $jar is older than required for language version $languageVersion")
|
||||
messageCollector.issue(jar.file, "Runtime JAR file has version ${jar.version} which is older than required for language version $languageVersion")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,31 +144,37 @@ object JvmRuntimeVersionsConsistencyChecker {
|
||||
val newestCoreJar = runtimeJarsInfo.coreJars.maxBy { it.version } ?: return
|
||||
|
||||
if (oldestCoreJar.version != newestCoreJar.version) {
|
||||
messageCollector.issue("Run-time JAR file $oldestCoreJar is not compatible with JAR file $newestCoreJar")
|
||||
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.coreJars) {
|
||||
appendln(" ${jar.file.path} (version ${jar.version})")
|
||||
}
|
||||
}.trimEnd())
|
||||
}
|
||||
}
|
||||
|
||||
private fun MessageCollector.issue(message: String) {
|
||||
report(VERSION_ISSUE_SEVERITY, message, CompilerMessageLocation.NO_LOCATION)
|
||||
private fun MessageCollector.issue(file: VirtualFile?, message: String) {
|
||||
report(VERSION_ISSUE_SEVERITY, message, CompilerMessageLocation.create(file?.let(VfsUtilCore::virtualToIoFile)?.path))
|
||||
}
|
||||
|
||||
private fun collectRuntimeJarsInfo(classpathJars: List<VirtualFile>): RuntimeJarsInfo {
|
||||
private fun collectRuntimeJarsInfo(classpathJarRoots: List<VirtualFile>): RuntimeJarsInfo {
|
||||
val kotlinCoreJars = ArrayList<KotlinLibraryFile>(2)
|
||||
|
||||
for (jar in classpathJars) {
|
||||
for (jarRoot in classpathJarRoots) {
|
||||
val manifest = try {
|
||||
val manifestFile = jar.findFileByRelativePath(MANIFEST_MF) ?: continue
|
||||
val manifestFile = jarRoot.findFileByRelativePath(MANIFEST_MF) ?: continue
|
||||
Manifest(manifestFile.inputStream)
|
||||
}
|
||||
catch (e: Exception) {
|
||||
continue
|
||||
}
|
||||
|
||||
val runtimeComponent = getKotlinRuntimeComponent(jar, manifest) ?: continue
|
||||
val runtimeComponent = getKotlinRuntimeComponent(jarRoot, manifest) ?: continue
|
||||
val version = manifest.getKotlinLanguageVersion()
|
||||
|
||||
if (runtimeComponent == KOTLIN_RUNTIME_COMPONENT_CORE) {
|
||||
kotlinCoreJars.add(KotlinLibraryFile(runtimeComponent, jar, version))
|
||||
val jarFile = VfsUtilCore.getVirtualFileForJar(jarRoot) ?: continue
|
||||
kotlinCoreJars.add(KotlinLibraryFile(runtimeComponent, jarFile, version))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -158,8 +158,8 @@ class KotlinCoreEnvironment private constructor(
|
||||
val messageCollector = configuration.get(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY)
|
||||
if (messageCollector != null) {
|
||||
val languageVersionSettings = configuration.get(CommonConfigurationKeys.LANGUAGE_VERSION_SETTINGS)
|
||||
val classpathJars = initialRoots.mapNotNull { if (it.type == JavaRoot.RootType.BINARY) it.file else null }
|
||||
JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency(messageCollector, languageVersionSettings, classpathJars)
|
||||
val classpathJarRoots = initialRoots.mapNotNull { (file, type) -> if (type == JavaRoot.RootType.BINARY) file else null }
|
||||
JvmRuntimeVersionsConsistencyChecker.checkCompilerClasspathConsistency(messageCollector, languageVersionSettings, classpathJarRoots)
|
||||
}
|
||||
|
||||
// REPL and kapt2 update classpath dynamically
|
||||
@@ -206,27 +206,26 @@ class KotlinCoreEnvironment private constructor(
|
||||
}
|
||||
|
||||
private fun Iterable<ContentRoot>.classpathRoots(): List<JavaRoot> =
|
||||
filterIsInstance(JvmContentRoot::class.java).mapNotNull {
|
||||
javaRoot -> contentRootToVirtualFile(javaRoot)?.let { virtualFile ->
|
||||
|
||||
val prefixPackageFqName = (javaRoot as? JavaSourceRoot)?.packagePrefix?.let {
|
||||
if (isValidJavaFqName(it)) {
|
||||
FqName(it)
|
||||
filterIsInstance(JvmContentRoot::class.java).mapNotNull { javaRoot ->
|
||||
contentRootToVirtualFile(javaRoot)?.let { virtualFile ->
|
||||
val prefixPackageFqName = (javaRoot as? JavaSourceRoot)?.packagePrefix?.let {
|
||||
if (isValidJavaFqName(it)) {
|
||||
FqName(it)
|
||||
}
|
||||
else {
|
||||
report(WARNING, "Invalid package prefix name is ignored: $it")
|
||||
null
|
||||
}
|
||||
}
|
||||
else {
|
||||
report(WARNING, "Invalid package prefix name is ignored: $it")
|
||||
null
|
||||
|
||||
val rootType = when (javaRoot) {
|
||||
is JavaSourceRoot -> JavaRoot.RootType.SOURCE
|
||||
is JvmClasspathRoot -> JavaRoot.RootType.BINARY
|
||||
else -> throw IllegalStateException()
|
||||
}
|
||||
}
|
||||
|
||||
val rootType = when (javaRoot) {
|
||||
is JavaSourceRoot -> JavaRoot.RootType.SOURCE
|
||||
is JvmClasspathRoot -> JavaRoot.RootType.BINARY
|
||||
else -> throw IllegalStateException()
|
||||
JavaRoot(virtualFile, rootType, prefixPackageFqName)
|
||||
}
|
||||
|
||||
JavaRoot(virtualFile, rootType, prefixPackageFqName)
|
||||
}
|
||||
}
|
||||
|
||||
private fun updateClasspathFromRootsIndex(index: JvmDependenciesIndex) {
|
||||
|
||||
Reference in New Issue
Block a user