Report incompatible metadata version error correctly
Similarly to pre-release classes, load metadata for the class anyway and allow the resolution to select it as the result and prohibit its usage in the end with the special diagnostic reported in MissingDependencyClassChecker
This commit is contained in:
@@ -35,6 +35,7 @@ import org.jetbrains.kotlin.resolve.calls.inference.InferenceErrorData;
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier;
|
||||
import org.jetbrains.kotlin.resolve.checkers.PlatformImplDeclarationChecker;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
@@ -83,6 +84,7 @@ public interface Errors {
|
||||
|
||||
DiagnosticFactory1<PsiElement, FqName> MISSING_DEPENDENCY_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory1<PsiElement, FqName> PRE_RELEASE_CLASS = DiagnosticFactory1.create(ERROR);
|
||||
DiagnosticFactory2<PsiElement, FqName, IncompatibleVersionErrorData<?>> INCOMPATIBLE_CLASS = DiagnosticFactory2.create(ERROR);
|
||||
|
||||
//Elements with "INVISIBLE_REFERENCE" error are marked as unresolved, unlike elements with "INVISIBLE_MEMBER" error
|
||||
//"INVISIBLE_REFERENCE" is used for invisible classes references and references in import
|
||||
|
||||
+13
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.kotlin.diagnostics.rendering;
|
||||
|
||||
import com.intellij.openapi.extensions.ExtensionPointName;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import kotlin.jvm.functions.Function1;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
@@ -31,6 +32,7 @@ import org.jetbrains.kotlin.psi.KtExpression;
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameExpression;
|
||||
import org.jetbrains.kotlin.psi.KtTypeConstraint;
|
||||
import org.jetbrains.kotlin.resolve.VarianceConflictDiagnosticData;
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData;
|
||||
import org.jetbrains.kotlin.types.KotlinType;
|
||||
import org.jetbrains.kotlin.util.MappedExtensionProvider;
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions;
|
||||
@@ -321,6 +323,17 @@ public class DefaultErrorMessages {
|
||||
|
||||
MAP.put(MISSING_DEPENDENCY_CLASS, "Cannot access class ''{0}''. Check your module classpath for missing or conflicting dependencies", TO_STRING);
|
||||
MAP.put(PRE_RELEASE_CLASS, "Class ''{0}'' is compiled by a pre-release version of Kotlin and cannot be loaded by this version of the compiler", TO_STRING);
|
||||
MAP.put(INCOMPATIBLE_CLASS,
|
||||
"Class ''{0}'' was compiled with an incompatible version of Kotlin. {1}",
|
||||
TO_STRING, new DiagnosticParameterRenderer<IncompatibleVersionErrorData<?>>() {
|
||||
@NotNull
|
||||
@Override
|
||||
public String render(@NotNull IncompatibleVersionErrorData<?> incompatibility, @NotNull RenderingContext renderingContext) {
|
||||
return "The binary version of its metadata is " + incompatibility.getActualVersion() +
|
||||
", expected version is " + incompatibility.getExpectedVersion() + ".\n" +
|
||||
"The class is loaded from " + FileUtil.toSystemIndependentName(incompatibility.getFilePath());
|
||||
}
|
||||
});
|
||||
|
||||
MAP.put(LOCAL_OBJECT_NOT_ALLOWED, "Named object ''{0}'' is a singleton and cannot be local. Try to use anonymous object instead", NAME);
|
||||
MAP.put(LOCAL_INTERFACE_NOT_ALLOWED, "''{0}'' is an interface so it cannot be local. Try to use anonymous object or abstract class instead", NAME);
|
||||
|
||||
+10
-5
@@ -23,8 +23,7 @@ import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.SourceElement
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.MISSING_DEPENDENCY_CLASS
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.PRE_RELEASE_CLASS
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||
import org.jetbrains.kotlin.resolve.BindingTrace
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallChecker
|
||||
import org.jetbrains.kotlin.resolve.calls.checkers.CallCheckerContext
|
||||
@@ -57,9 +56,15 @@ object MissingDependencyClassChecker : CallChecker {
|
||||
}
|
||||
|
||||
private fun incompatibilityDiagnosticFor(source: SourceElement?, reportOn: PsiElement): Diagnostic? {
|
||||
if (source is DeserializedContainerSource && 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)
|
||||
if (source is DeserializedContainerSource) {
|
||||
val incompatibility = source.incompatibility
|
||||
if (incompatibility != null) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
Reference in New Issue
Block a user