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:
+13
-18
@@ -99,25 +99,20 @@ class LazyJavaPackageScope(
|
||||
object SyntheticClass : KotlinClassLookupResult()
|
||||
}
|
||||
|
||||
private fun resolveKotlinBinaryClass(kotlinClass: KotlinJvmBinaryClass?): KotlinClassLookupResult {
|
||||
if (kotlinClass == null) return KotlinClassLookupResult.NotFound
|
||||
|
||||
val header = kotlinClass.classHeader
|
||||
return when {
|
||||
!header.metadataVersion.isCompatible() -> {
|
||||
c.components.errorReporter.reportIncompatibleMetadataVersion(kotlinClass.classId, kotlinClass.location, header.metadataVersion)
|
||||
KotlinClassLookupResult.NotFound
|
||||
private fun resolveKotlinBinaryClass(kotlinClass: KotlinJvmBinaryClass?): KotlinClassLookupResult =
|
||||
when {
|
||||
kotlinClass == null -> {
|
||||
KotlinClassLookupResult.NotFound
|
||||
}
|
||||
kotlinClass.classHeader.kind == KotlinClassHeader.Kind.CLASS -> {
|
||||
val descriptor = c.components.deserializedDescriptorResolver.resolveClass(kotlinClass)
|
||||
if (descriptor != null) KotlinClassLookupResult.Found(descriptor) else KotlinClassLookupResult.NotFound
|
||||
}
|
||||
else -> {
|
||||
// This is a package or interface DefaultImpls or something like that
|
||||
KotlinClassLookupResult.SyntheticClass
|
||||
}
|
||||
}
|
||||
header.kind == KotlinClassHeader.Kind.CLASS -> {
|
||||
val descriptor = c.components.deserializedDescriptorResolver.resolveClass(kotlinClass)
|
||||
if (descriptor != null) KotlinClassLookupResult.Found(descriptor) else KotlinClassLookupResult.NotFound
|
||||
}
|
||||
else -> {
|
||||
// This is a package or interface DefaultImpls or something like that
|
||||
KotlinClassLookupResult.SyntheticClass
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// javaClass here is only for sake of optimizations
|
||||
private class FindClassRequest(val name: Name, val javaClass: JavaClass?) {
|
||||
|
||||
+15
-9
@@ -25,8 +25,10 @@ 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
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
import org.jetbrains.kotlin.utils.sure
|
||||
import javax.inject.Inject
|
||||
|
||||
@@ -50,7 +52,11 @@ class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) {
|
||||
val classData = parseProto(kotlinClass) {
|
||||
JvmProtoBufUtil.readClassDataFrom(data, strings)
|
||||
}
|
||||
val sourceElement = KotlinJvmBinarySourceElement(kotlinClass, !IS_PRE_RELEASE && kotlinClass.classHeader.isPreRelease)
|
||||
val sourceElement = KotlinJvmBinarySourceElement(
|
||||
kotlinClass,
|
||||
kotlinClass.incompatibility,
|
||||
!IS_PRE_RELEASE && kotlinClass.classHeader.isPreRelease
|
||||
)
|
||||
return ClassDataWithSource(classData, sourceElement)
|
||||
}
|
||||
|
||||
@@ -62,6 +68,7 @@ class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) {
|
||||
}
|
||||
val source = JvmPackagePartSource(
|
||||
kotlinClass,
|
||||
kotlinClass.incompatibility,
|
||||
isPreReleaseInvisible = !IS_PRE_RELEASE && kotlinClass.classHeader.isPreRelease
|
||||
)
|
||||
return DeserializedPackageMemberScope(descriptor, packageProto, nameResolver, source, components) {
|
||||
@@ -70,16 +77,15 @@ class DeserializedDescriptorResolver(private val errorReporter: ErrorReporter) {
|
||||
}
|
||||
}
|
||||
|
||||
private fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? {
|
||||
val header = kotlinClass.classHeader
|
||||
if (!header.metadataVersion.isCompatible()) {
|
||||
errorReporter.reportIncompatibleMetadataVersion(kotlinClass.classId, kotlinClass.location, header.metadataVersion)
|
||||
}
|
||||
else if (expectedKinds.contains(header.kind)) {
|
||||
return header.data
|
||||
private val KotlinJvmBinaryClass.incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>?
|
||||
get() {
|
||||
if (classHeader.metadataVersion.isCompatible()) return null
|
||||
return IncompatibleVersionErrorData(classHeader.metadataVersion, JvmMetadataVersion.INSTANCE, location, classId)
|
||||
}
|
||||
|
||||
return null
|
||||
internal fun readData(kotlinClass: KotlinJvmBinaryClass, expectedKinds: Set<KotlinClassHeader.Kind>): Array<String>? {
|
||||
val header = kotlinClass.classHeader
|
||||
return (header.data ?: header.incompatibleData)?.check { header.kind in expectedKinds }
|
||||
}
|
||||
|
||||
private inline fun <T> parseProto(klass: KotlinJvmBinaryClass, block: () -> T): T {
|
||||
|
||||
+8
-1
@@ -21,18 +21,25 @@ import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.jvm.JvmClassName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
class JvmPackagePartSource(
|
||||
val className: JvmClassName,
|
||||
val facadeClassName: JvmClassName?,
|
||||
override val incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>? = null,
|
||||
override val isPreReleaseInvisible: Boolean = false
|
||||
) : DeserializedContainerSource {
|
||||
constructor(kotlinClass: KotlinJvmBinaryClass, isPreReleaseInvisible: Boolean = false) : this(
|
||||
constructor(
|
||||
kotlinClass: KotlinJvmBinaryClass,
|
||||
incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>? = null,
|
||||
isPreReleaseInvisible: Boolean = false
|
||||
) : this(
|
||||
JvmClassName.byClassId(kotlinClass.classId),
|
||||
kotlinClass.classHeader.multifileClassName?.let {
|
||||
if (it.isNotEmpty()) JvmClassName.byInternalName(it) else null
|
||||
},
|
||||
incompatibility,
|
||||
isPreReleaseInvisible
|
||||
)
|
||||
|
||||
|
||||
+2
@@ -18,10 +18,12 @@ package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.SourceFile
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.deserialization.IncompatibleVersionErrorData
|
||||
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedContainerSource
|
||||
|
||||
class KotlinJvmBinarySourceElement(
|
||||
val binaryClass: KotlinJvmBinaryClass,
|
||||
override val incompatibility: IncompatibleVersionErrorData<JvmMetadataVersion>? = null,
|
||||
override val isPreReleaseInvisible: Boolean = false
|
||||
) : DeserializedContainerSource {
|
||||
override val presentableFqName: FqName
|
||||
|
||||
+1
@@ -27,6 +27,7 @@ class KotlinClassHeader(
|
||||
val metadataVersion: JvmMetadataVersion,
|
||||
val bytecodeVersion: JvmBytecodeBinaryVersion,
|
||||
val data: Array<String>?,
|
||||
val incompatibleData: Array<String>?,
|
||||
val strings: Array<String>?,
|
||||
val extraString: String?,
|
||||
val extraInt: Int
|
||||
|
||||
+6
@@ -54,6 +54,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
private int extraInt = 0;
|
||||
private String[] data = null;
|
||||
private String[] strings = null;
|
||||
private String[] incompatibleData = null;
|
||||
private KotlinClassHeader.Kind headerKind = null;
|
||||
|
||||
@Nullable
|
||||
@@ -62,6 +63,10 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!metadataVersion.isCompatible()) {
|
||||
incompatibleData = data;
|
||||
}
|
||||
|
||||
if (metadataVersion == null || !metadataVersion.isCompatible()) {
|
||||
data = null;
|
||||
}
|
||||
@@ -76,6 +81,7 @@ public class ReadKotlinClassHeaderAnnotationVisitor implements AnnotationVisitor
|
||||
metadataVersion != null ? metadataVersion : JvmMetadataVersion.INVALID_VERSION,
|
||||
bytecodeVersion != null ? bytecodeVersion : JvmBytecodeBinaryVersion.INVALID_VERSION,
|
||||
data,
|
||||
incompatibleData,
|
||||
strings,
|
||||
extraString,
|
||||
extraInt
|
||||
|
||||
Reference in New Issue
Block a user