From 513ebb9729178fc5e339f7b06dbb767f6bccf0ca Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 8 Dec 2016 12:11:06 +0300 Subject: [PATCH] Suggest to use "-Xskip-metadata-version-check" on incompatible classes in classpath --- .../messages/AnalyzerWithCompilerReport.kt | 31 ++++++++++++++----- .../checkers/MissingDependencyClassChecker.kt | 1 - compiler/testData/cli/jvm/wrongAbiVersion.out | 1 + .../cli/jvm/wrongAbiVersionNoErrors.out | 1 + .../output.txt | 1 + .../wrongMetadataVersion/output.txt | 1 + 6 files changed, 27 insertions(+), 9 deletions(-) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt index b3f62280f20..640b5716450 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/messages/AnalyzerWithCompilerReport.kt @@ -24,11 +24,8 @@ import com.intellij.psi.PsiModifierListOwner import com.intellij.psi.util.PsiFormatUtil import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.codegen.state.IncompatibleClassTrackerImpl -import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0 +import org.jetbrains.kotlin.diagnostics.* import org.jetbrains.kotlin.diagnostics.DiagnosticUtils.sortedDiagnostics -import org.jetbrains.kotlin.diagnostics.Severity -import org.jetbrains.kotlin.diagnostics.SimpleDiagnostic import org.jetbrains.kotlin.diagnostics.rendering.DefaultErrorMessages import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter @@ -143,16 +140,34 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector) return diagnostic.severity == Severity.ERROR } - fun reportDiagnostics(diagnostics: Diagnostics, reporter: DiagnosticMessageReporter): Boolean { + data class ReportDiagnosticsResult(val hasErrors: Boolean, val hasIncompatibleClassErrors: Boolean) + + fun reportDiagnostics(unsortedDiagnostics: Diagnostics, reporter: DiagnosticMessageReporter): ReportDiagnosticsResult { var hasErrors = false - for (diagnostic in sortedDiagnostics(diagnostics.all())) { + var hasIncompatibleClassErrors = false + val diagnostics = sortedDiagnostics(unsortedDiagnostics.all()) + for (diagnostic in diagnostics) { hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter) + hasIncompatibleClassErrors = hasIncompatibleClassErrors or + (diagnostic.factory == Errors.INCOMPATIBLE_CLASS || diagnostic.factory == Errors.PRE_RELEASE_CLASS) } - return hasErrors + + return ReportDiagnosticsResult(hasErrors, hasIncompatibleClassErrors) } fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean { - return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector)) + val (hasErrors, hasIncompatibleClassErrors) = reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector)) + + if (hasIncompatibleClassErrors) { + messageCollector.report( + CompilerMessageSeverity.ERROR, + "Incompatible classes were found in dependencies. " + + "Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors", + CompilerMessageLocation.NO_LOCATION + ) + } + + return hasErrors } fun reportSyntaxErrors( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt index 281ce51fd36..4fa4b91b9bd 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/MissingDependencyClassChecker.kt @@ -62,7 +62,6 @@ object MissingDependencyClassChecker : CallChecker { return INCOMPATIBLE_CLASS.on(reportOn, source.presentableFqName, incompatibility) } if (source.isPreReleaseInvisible) { - // TODO: if at least one PRE_RELEASE_CLASS is reported, display a hint to disable the diagnostic return PRE_RELEASE_CLASS.on(reportOn, source.presentableFqName) } } diff --git a/compiler/testData/cli/jvm/wrongAbiVersion.out b/compiler/testData/cli/jvm/wrongAbiVersion.out index 8d4f58dd56d..d2baad09b16 100644 --- a/compiler/testData/cli/jvm/wrongAbiVersion.out +++ b/compiler/testData/cli/jvm/wrongAbiVersion.out @@ -1,3 +1,4 @@ +error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors compiler/testData/cli/jvm/wrongAbiVersion.kt:3:12: error: class 'ClassWithWrongAbiVersion' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 0.30.0, expected version is $ABI_VERSION$. The class is loaded from $TESTDATA_DIR$/wrongAbiVersionLib/bin/ClassWithWrongAbiVersion.class fun foo(x: ClassWithWrongAbiVersion) { diff --git a/compiler/testData/cli/jvm/wrongAbiVersionNoErrors.out b/compiler/testData/cli/jvm/wrongAbiVersionNoErrors.out index 2ffc0d49882..d4c9a3f0a8a 100644 --- a/compiler/testData/cli/jvm/wrongAbiVersionNoErrors.out +++ b/compiler/testData/cli/jvm/wrongAbiVersionNoErrors.out @@ -1,3 +1,4 @@ +error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors compiler/testData/cli/jvm/wrongAbiVersionNoErrors.kt:3:14: error: class 'wrong.ClassWithInnerLambda' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 0.30.0, expected version is $ABI_VERSION$. The class is loaded from $TESTDATA_DIR$/wrongAbiVersionLib/bin/wrong/ClassWithInnerLambda.class import wrong.ClassWithInnerLambda diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/output.txt index 1af8e443240..746efd8b93d 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/releaseCompilerAgainstPreReleaseLibrary/output.txt @@ -1,3 +1,4 @@ +error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-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) { ^ diff --git a/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt b/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt index caea6212ce9..11740f7aba7 100644 --- a/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt +++ b/compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/output.txt @@ -1,3 +1,4 @@ +error: incompatible classes were found in dependencies. Remove them from the classpath or use '-Xskip-metadata-version-check' to suppress errors compiler/testData/compileKotlinAgainstCustomBinaries/wrongMetadataVersion/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) {