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 com.intellij.psi.util.PsiFormatUtil
import org.jetbrains.kotlin.analyzer.AnalysisResult import org.jetbrains.kotlin.analyzer.AnalysisResult
import org.jetbrains.kotlin.codegen.state.IncompatibleClassTrackerImpl 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.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.diagnostics.rendering.DefaultErrorMessages
import org.jetbrains.kotlin.load.java.JvmBytecodeBinaryVersion
import org.jetbrains.kotlin.load.java.components.TraceBasedErrorReporter 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.psi.KtFile
import org.jetbrains.kotlin.resolve.AnalyzingUtils import org.jetbrains.kotlin.resolve.AnalyzingUtils
import org.jetbrains.kotlin.resolve.BindingContext 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.JvmBindingContextSlices
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import java.util.*
class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector) { class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector) {
lateinit var analysisResult: AnalysisResult 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>) { private fun reportSyntaxErrors(files: Collection<KtFile>) {
for (file in files) { for (file in files) {
reportSyntaxErrors(file, messageCollector) reportSyntaxErrors(file, messageCollector)
@@ -126,9 +109,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
if (analysisResult.bindingContext.diagnostics.any { it.isValid && it.severity == Severity.ERROR }) { if (analysisResult.bindingContext.diagnostics.any { it.isValid && it.severity == Severity.ERROR }) {
analyzer.reportEnvironmentErrors() analyzer.reportEnvironmentErrors()
} }
val abiVersionErrors = abiVersionErrors reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector)
reportDiagnostics(analysisResult.bindingContext.diagnostics, messageCollector, !abiVersionErrors.isEmpty())
reportMetadataVersionErrors(abiVersionErrors)
reportIncompleteHierarchies() reportIncompleteHierarchies()
reportAlternativeSignatureErrors() reportAlternativeSignatureErrors()
} }
@@ -150,51 +131,28 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
private val SYNTAX_ERROR_FACTORY = DiagnosticFactory0.create<PsiErrorElement>(Severity.ERROR) private val SYNTAX_ERROR_FACTORY = DiagnosticFactory0.create<PsiErrorElement>(Severity.ERROR)
private fun reportDiagnostic( private fun reportDiagnostic(diagnostic: Diagnostic, reporter: DiagnosticMessageReporter): Boolean {
diagnostic: Diagnostic,
reporter: DiagnosticMessageReporter,
incompatibleFilesFound: Boolean): Boolean {
if (!diagnostic.isValid) return false if (!diagnostic.isValid) return false
var render: String = if (diagnostic is MyDiagnostic<*>) { reporter.report(
diagnostic.message diagnostic,
} diagnostic.psiFile,
else { (diagnostic as? MyDiagnostic<*>)?.message ?: DefaultErrorMessages.render(diagnostic)
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)
return diagnostic.severity == Severity.ERROR return diagnostic.severity == Severity.ERROR
} }
fun reportDiagnostics( fun reportDiagnostics(diagnostics: Diagnostics, reporter: DiagnosticMessageReporter): Boolean {
diagnostics: Diagnostics,
reporter: DiagnosticMessageReporter,
incompatibleFilesFound: Boolean): Boolean {
var hasErrors = false var hasErrors = false
for (diagnostic in sortedDiagnostics(diagnostics.all())) { for (diagnostic in sortedDiagnostics(diagnostics.all())) {
hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter, incompatibleFilesFound) hasErrors = hasErrors or reportDiagnostic(diagnostic, reporter)
} }
return hasErrors return hasErrors
} }
fun reportDiagnostics(
diagnostics: Diagnostics,
messageCollector: MessageCollector,
incompatibleFilesFound: Boolean): Boolean {
return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector), incompatibleFilesFound)
}
fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean { fun reportDiagnostics(diagnostics: Diagnostics, messageCollector: MessageCollector): Boolean {
return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector), false) return reportDiagnostics(diagnostics, DefaultDiagnosticReporter(messageCollector))
} }
fun reportSyntaxErrors( fun reportSyntaxErrors(
@@ -206,7 +164,7 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
private fun <E : PsiElement> reportDiagnostic(element: E, factory: DiagnosticFactory0<E>, message: String) { private fun <E : PsiElement> reportDiagnostic(element: E, factory: DiagnosticFactory0<E>, message: String) {
val diagnostic = MyDiagnostic(element, factory, message) val diagnostic = MyDiagnostic(element, factory, message)
AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter, false) AnalyzerWithCompilerReport.reportDiagnostic(diagnostic, reporter)
if (element.textRange.startOffset != file.textRange.endOffset) { if (element.textRange.startOffset != file.textRange.endOffset) {
allErrorsAtEof = false allErrorsAtEof = false
} }
@@ -243,20 +201,19 @@ class AnalyzerWithCompilerReport(private val messageCollector: MessageCollector)
for (location in locations) { for (location in locations) {
val data = bindingContext.get(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS, location) val data = bindingContext.get(IncompatibleClassTrackerImpl.BYTECODE_VERSION_ERRORS, location)
?: error("Value is missing for key in binding context: " + location) ?: error("Value is missing for key in binding context: " + location)
reportIncompatibleBinaryVersion(messageCollector, data, "bytecode", severity) reportIncompatibleBinaryVersion(messageCollector, data, severity)
} }
} }
private fun reportIncompatibleBinaryVersion( private fun reportIncompatibleBinaryVersion(
messageCollector: MessageCollector, messageCollector: MessageCollector,
data: IncompatibleVersionErrorData<*>, data: IncompatibleVersionErrorData<JvmBytecodeBinaryVersion>,
versionSortText: String, severity: CompilerMessageSeverity
severity: CompilerMessageSeverity) { ) {
messageCollector.report( messageCollector.report(
severity, severity,
"Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " + "Class '" + JvmClassName.byClassId(data.classId) + "' was compiled with an incompatible version of Kotlin. " +
"The binary version of its " + versionSortText + " is " + data.actualVersion + ", " + "The binary version of its bytecode is " + data.actualVersion + ", expected version is " + data.expectedVersion,
"expected version is " + data.expectedVersion,
CompilerMessageLocation.create(toSystemDependentName(data.filePath), -1, -1, null) CompilerMessageLocation.create(toSystemDependentName(data.filePath), -1, -1, null)
) )
} }
@@ -135,7 +135,7 @@ open class GenericReplCompiler(
} }
val analysisResult = analyzerEngine.analyzeReplLine(psiFile, codeLine.no) val analysisResult = analyzerEngine.analyzeReplLine(psiFile, codeLine.no)
AnalyzerWithCompilerReport.Companion.reportDiagnostics(analysisResult.diagnostics, errorHolder, false) AnalyzerWithCompilerReport.Companion.reportDiagnostics(analysisResult.diagnostics, errorHolder)
val scriptDescriptor = when (analysisResult) { val scriptDescriptor = when (analysisResult) {
is CliReplAnalyzerEngine.ReplLineAnalysisResult.WithErrors -> return ReplCompileResult.Error(errorHolder.renderedDiagnostics) is CliReplAnalyzerEngine.ReplLineAnalysisResult.WithErrors -> return ReplCompileResult.Error(errorHolder.renderedDiagnostics)
is CliReplAnalyzerEngine.ReplLineAnalysisResult.Successful -> analysisResult.scriptDescriptor is CliReplAnalyzerEngine.ReplLineAnalysisResult.Successful -> analysisResult.scriptDescriptor
@@ -100,7 +100,7 @@ class ReplInterpreter(
} }
val analysisResult = analyzerEngine.analyzeReplLine(psiFile, lineNumber) val analysisResult = analyzerEngine.analyzeReplLine(psiFile, lineNumber)
AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder, false) AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder)
val scriptDescriptor = when (analysisResult) { val scriptDescriptor = when (analysisResult) {
is WithErrors -> return LineResult.Error.CompileTime(errorHolder.renderedDiagnostics) is WithErrors -> return LineResult.Error.CompileTime(errorHolder.renderedDiagnostics)
is Successful -> analysisResult.scriptDescriptor 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.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor 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.BindingTrace
import org.jetbrains.kotlin.resolve.OverrideResolver 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.ErrorReporter
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice import org.jetbrains.kotlin.util.slicedMap.BasicWritableSlice
import org.jetbrains.kotlin.util.slicedMap.Slices import org.jetbrains.kotlin.util.slicedMap.Slices
import org.jetbrains.kotlin.util.slicedMap.WritableSlice import org.jetbrains.kotlin.util.slicedMap.WritableSlice
class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter { class TraceBasedErrorReporter(private val trace: BindingTrace) : ErrorReporter {
companion object { companion object {
@JvmField
val METADATA_VERSION_ERRORS: WritableSlice<String, IncompatibleVersionErrorData<JvmMetadataVersion>> = Slices.createCollectiveSlice()
@JvmField @JvmField
val INCOMPLETE_HIERARCHY: WritableSlice<ClassDescriptor, List<String>> = Slices.createCollectiveSlice() 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>) { override fun reportIncompleteHierarchy(descriptor: ClassDescriptor, unresolvedSuperClasses: List<String>) {
trace.record(INCOMPLETE_HIERARCHY, descriptor, unresolvedSuperClasses) 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.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.ClassDataWithSource import org.jetbrains.kotlin.serialization.ClassDataWithSource
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents 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.IncompatibleVersionErrorData
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.serialization.jvm.JvmProtoBufUtil 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 org.jetbrains.kotlin.utils.sure
import javax.inject.Inject import javax.inject.Inject
class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) { class DeserializedDescriptorResolver {
lateinit var components: DeserializationComponents lateinit var components: DeserializationComponents
// component dependency cycle // 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.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor 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 import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
object RuntimeErrorReporter : ErrorReporter { object RuntimeErrorReporter : ErrorReporter {
@@ -29,14 +26,8 @@ object RuntimeErrorReporter : ErrorReporter {
throw IllegalStateException("Incomplete hierarchy for class ${descriptor.name}, unresolved classes $unresolvedSuperClasses") 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) { override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
// TODO: use DescriptorRenderer // TODO: use DescriptorRenderer
throw IllegalStateException("Cannot infer visibility for $descriptor") 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 module = ModuleDescriptorImpl(Name.special("<runtime module for $classLoader>"), storageManager, builtIns)
val reflectKotlinClassFinder = ReflectKotlinClassFinder(classLoader) val reflectKotlinClassFinder = ReflectKotlinClassFinder(classLoader)
val deserializedDescriptorResolver = DeserializedDescriptorResolver(RuntimeErrorReporter) val deserializedDescriptorResolver = DeserializedDescriptorResolver()
val singleModuleClassResolver = SingleModuleClassResolver() val singleModuleClassResolver = SingleModuleClassResolver()
val runtimePackageFacadeProvider = RuntimePackagePartProvider(classLoader) val runtimePackageFacadeProvider = RuntimePackagePartProvider(classLoader)
val javaResolverCache = JavaResolverCache.EMPTY val javaResolverCache = JavaResolverCache.EMPTY
@@ -19,24 +19,15 @@ package org.jetbrains.kotlin.serialization.deserialization;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor; import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor;
import org.jetbrains.kotlin.descriptors.ClassDescriptor; import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.name.ClassId;
import java.util.List; import java.util.List;
public interface ErrorReporter { public interface ErrorReporter {
void reportIncompatibleMetadataVersion(@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion);
void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses); void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses);
void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor); void reportCannotInferVisibility(@NotNull CallableMemberDescriptor descriptor);
ErrorReporter DO_NOTHING = new ErrorReporter() { ErrorReporter DO_NOTHING = new ErrorReporter() {
@Override
public void reportIncompatibleMetadataVersion(
@NotNull ClassId classId, @NotNull String filePath, @NotNull BinaryVersion actualVersion
) {
}
@Override @Override
public void reportIncompleteHierarchy(@NotNull ClassDescriptor descriptor, @NotNull List<String> unresolvedSuperClasses) { 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 com.intellij.openapi.diagnostic.Logger
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ClassDescriptor 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 import org.jetbrains.kotlin.serialization.deserialization.ErrorReporter
class LoggingErrorReporter(private val log: Logger) : ErrorReporter { class LoggingErrorReporter(private val log: Logger) : ErrorReporter {
@@ -31,8 +29,4 @@ class LoggingErrorReporter(private val log: Logger) : ErrorReporter {
override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) { override fun reportCannotInferVisibility(descriptor: CallableMemberDescriptor) {
log.error("Could not infer visibility for $descriptor") 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")
}
} }