Remove old mechanism of metadata version error reporting

This commit is contained in:
Alexander Udalov
2016-12-07 18:27:58 +03:00
parent b943ed26f3
commit 789483e1eb
9 changed files with 25 additions and 104 deletions
@@ -24,11 +24,14 @@ 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.*
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0
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
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingContext
@@ -38,7 +41,6 @@ import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.resolve.jvm.JvmBindingContextSlices
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import java.util.*
class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector) {
lateinit var analysisResult: AnalysisResult
@@ -82,25 +84,6 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
}
}
private val abiVersionErrors: List<IncompatibleVersionErrorData<JvmMetadataVersion>>
get() {
val bindingContext = analysisResult.bindingContext
val errorClasses = bindingContext.getKeys(TraceBasedErrorReporter.METADATA_VERSION_ERRORS)
val result = ArrayList<IncompatibleVersionErrorData<JvmMetadataVersion>>(errorClasses.size)
for (kotlinClass in errorClasses) {
result.add(bindingContext.get(TraceBasedErrorReporter.METADATA_VERSION_ERRORS, kotlinClass)!!)
}
return result
}
private fun reportMetadataVersionErrors(errors: List<IncompatibleVersionErrorData<JvmMetadataVersion>>) {
for (data in errors) {
reportIncompatibleBinaryVersion(messageCollector, data, "metadata", CompilerMessageSeverity.ERROR)
}
}
private fun reportSyntaxErrors(files: Collection<KtFile>) {
for (file in files) {
reportSyntaxErrors(file, messageCollector)
@@ -126,9 +109,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
if (analysisResult.bindingContext.diagnostics.any { it.isValid && it.severity == Severity.ERROR }) {
analyzer.reportEnvironmentErrors()
}
val abiVersionErrors = abiVersionErrors
reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector, !abiVersionErrors.isEmpty())
reportMetadataVersionErrors(abiVersionErrors)
reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector)
reportIncompleteHierarchies()
reportAlternativeSignatureErrors()
}
@@ -150,51 +131,28 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
private val SYNTAX_ERROR_FACTORY = DiagnosticFactory0.create<PsiErrorElement>(Severity.ERROR)
private fun reportDiagnostic(
diagnostic: Diagnostic,
reporter: DiagnosticMessageReporter,
incompatibleFilesFound: Boolean): Boolean {
private fun reportDiagnostic(diagnostic: Diagnostic, reporter: DiagnosticMessageReporter): Boolean {
if (!diagnostic.isValid) return false
var render: String = if (diagnostic is MyDiagnostic<*>) {
diagnostic.message
}
else {
DefaultErrorMessages.render(diagnostic)
}
if (incompatibleFilesFound && diagnostic.factory in Errors.UNRESOLVED_REFERENCE_DIAGNOSTICS) {
render += "\n(note: this may be caused by the fact that some classes compiled with an incompatible version of Kotlin " +
"were found in the classpath. Such classes cannot be loaded properly by this version of Kotlin compiler. " +
"See below for more information)"
}
val file = diagnostic.psiFile
reporter.report(diagnostic, file, render)
reporter.report(
diagnostic,
diagnostic.psiFile,
(diagnostic as? MyDiagnostic<*>)?.message ?: DefaultErrorMessages.render(diagnostic)
)
return diagnostic.severity == Severity.ERROR
}
fun reportDiagnostics(
diagnostics: Diagnostics,
reporter: DiagnosticMessageReporter,
incompatibleFilesFound: Boolean): Boolean {
fun reportDiagnostics(diagnostics: Diagnostics, reporter: DiagnosticMessageReporter): Boolean {
var hasErrors = false
for (diagnostic in sortedDiagnostics(diagnostics.all())) {
hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter, incompatibleFilesFound)
hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter)
}
return hasErrors
}
fun reportDiagnostics(
diagnostics: Diagnostics,
messageCollector: MessageCollector,
incompatibleFilesFound: Boolean): Boolean {
return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector), incompatibleFilesFound)
}
fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean {
return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector), false)
return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector))
}
fun reportSyntaxErrors(
@@ -206,7 +164,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
private fun <E : PsiElement> reportDiagnostic(element: E, factory: DiagnosticFactory0<E>, message: String) {
val diagnostic = MyDiagnostic(element, factory, message)
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter, false)
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter)
if (element.textRange.startOffset != file.textRange.endOffset) {
allErrorsAtEof = false
}
@@ -243,20 +201,19 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
for (location in locations) {
val data = bindingContext.get(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS, location)
?: error("Value is missing for key in binding context: " + location)
reportIncompatibleBinaryVersion(messageCollector, data, "bytecode", severity)
reportIncompatibleBinaryVersion(messageCollector, data, severity)
}
}
private fun reportIncompatibleBinaryVersion(
messageCollector: MessageCollector,
data: IncompatibleVersionErrorData<*>,
versionSortText: String,
severity: CompilerMessageSeverity) {
data: IncompatibleVersionErrorData<JvmBytecodeBinaryVersion>,
severity: CompilerMessageSeverity
) {
messageCollector.report(
severity,
"Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " +
"The binary version of its " + versionSortText + " is " + data.actualVersion + ", " +
"expected version is " + data.expectedVersion,
"The binary version of its bytecode is " + data.actualVersion + ", expected version is " + data.expectedVersion,
CompilerMessageLocation.create(toSystemDependentName(data.filePath), -1, -1, null)
)
}
@@ -135,7 +135,7 @@ open class GenericReplCompiler(
}
val analysisResult = analyzerEngine.analyzeReplLine(psiFile, codeLine.no)
AnalyzerWithCompilerReport.Companion.reportDiagnostics(analysisResult.diagnostics, errorHolder, false)
AnalyzerWithCompilerReport.Companion.reportDiagnostics(analysisResult.diagnostics, errorHolder)
val scriptDescriptor = when (analysisResult) {
is CliReplAnalyzerEngine.ReplLineAnalysisResult.WithErrors -> return ReplCompileResult.Error(errorHolder.renderedDiagnostics)
is CliReplAnalyzerEngine.ReplLineAnalysisResult.Successful -> analysisResult.scriptDescriptor
@@ -100,7 +100,7 @@ class ReplInterpreter(
}
val analysisResult = analyzerEngine.analyzeReplLine(psiFile, lineNumber)
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder, false)
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder)
val scriptDescriptor = when (analysisResult) {
is WithErrors -> return LineResult.Error.CompileTime(errorHolder.renderedDiagnostics)
is Successful -> analysisResult.scriptDescriptor
@@ -18,22 +18,15 @@ package org.jetbrains.kotlin.load.java.components
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.resolve.BindingTrace
import org.jetbrains.kotlin.resolve.OverrideResolver
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice
import org.jetbrains.kotlin.util.slicedMap.Slices
import org.jetbrains.kotlin.util.slicedMap.WritableSlice
class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter {
companion object {
@JvmField
val METADATA_VERSION_ERRORS: WritableSlice<String, IncompatibleVersionErrorData<JvmMetadataVersion>> = Slices.createCollectiveSlice()
@JvmField
val INCOMPLETE_HIERARCHY: WritableSlice<ClassDescriptor, List<String>> = Slices.createCollectiveSlice()
@@ -42,10 +35,6 @@ class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter {
}
}
override fun reportIncompatibleMetadataVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
trace.record(METADATA_VERSION_ERRORS, filePath, IncompatibleVersionErrorData(actualVersion as JvmMetadataVersion, JvmMetadataVersion.INSTANCE, filePath, classId))
}
override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: List<String>) {
trace.record(INCOMPLETE_HIERARCHY, descriptor, unresolvedSuperClasses)
}
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.protobuf.InvalidProtocolBufferException
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.ClassDataWithSource
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil
@@ -32,7 +31,7 @@ import org.jetbrains.kotlin.utils.addToStdlib.check
import org.jetbrains.kotlin.utils.sure
import javax.inject.Inject
class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) {
class DeserializedDescriptorResolver {
lateinit var components: DeserializationComponents
// component dependency cycle
@@ -18,9 +18,6 @@ package org.jetbrains.kotlin.load.java.components
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.load.kotlin.JvmMetadataVersion
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
object RuntimeErrorReporter : ErrorReporter {
@@ -29,14 +26,8 @@ object RuntimeErrorReporter : ErrorReporter {
throw IllegalStateException("Incomplete hierarchy for class ${descriptor.name}, unresolved classes $unresolvedSuperClasses")
}
override fun reportIncompatibleMetadataVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
throw IllegalStateException("Incompatible binary version of $classId: $actualVersion " +
"(expected version is ${JvmMetadataVersion.INSTANCE})")
}
override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
// TODO: use DescriptorRenderer
throw IllegalStateException("Cannot infer visibility for $descriptor")
}
}
@@ -48,7 +48,7 @@ class RuntimeModuleData private constructor(val deserialization: Deserialization
val module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), storageManager, builtIns)
val reflectKotlinClassFinder = ReflectKotlinClassFinder(classLoader)
val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter)
val deserializedDescriptorResolver = DeserializedDescriptorResolver()
val singleModuleClassResolver = SingleModuleClassResolver()
val runtimePackageFacadeProvider = RuntimePackagePartProvider(classLoader)
val javaResolverCache = JavaResolverCache.EMPTY
@@ -19,24 +19,15 @@ package org.jetbrains.kotlin.serialization.deserialization;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.name.ClassId;
import java.util.List;
public interface ErrorReporter {
void reportIncompatibleMetadataVersion(@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion);
void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses);
void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor);
ErrorReporter DO_NOTHING = new ErrorReporter() {
@Override
public void reportIncompatibleMetadataVersion(
@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion
) {
}
@Override
public void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses) {
}
@@ -19,8 +19,6 @@ package org.jetbrains.kotlin.idea.decompiler.textBuilder
import com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.BinaryVersion
import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
class LoggingErrorReporter(private val log: Logger) : ErrorReporter {
@@ -31,8 +29,4 @@ class LoggingErrorReporter(private val log: Logger) : ErrorReporter {
override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
log.error("Could not infer visibility for $descriptor")
}
override fun reportIncompatibleMetadataVersion(classId: ClassId, filePath: String, actualVersion: BinaryVersion) {
log.error("Incompatible ABI version for class $classId, actual version: $actualVersion")
}
}