Report error on incompatible .kotlin_module files in classpath
Also remove obsolete test wrongAbiVersionNoErrors #KT-25973 Fixed #KT-26266 Open
This commit is contained in:
@@ -5,17 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.load.kotlin
|
||||
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||
|
||||
fun ModuleMapping.Companion.loadModuleMapping(
|
||||
bytes: ByteArray?,
|
||||
debugName: String,
|
||||
configuration: DeserializationConfiguration
|
||||
configuration: DeserializationConfiguration,
|
||||
reportIncompatibleVersionError: (JvmMetadataVersion) -> Unit
|
||||
): ModuleMapping =
|
||||
loadModuleMapping(
|
||||
bytes,
|
||||
debugName,
|
||||
configuration.skipMetadataVersionCheck,
|
||||
configuration.isJvmPackageNameSupported
|
||||
configuration.isJvmPackageNameSupported,
|
||||
reportIncompatibleVersionError
|
||||
)
|
||||
|
||||
+11
-1
@@ -18,6 +18,7 @@ package kotlin.reflect.jvm.internal.components
|
||||
|
||||
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
|
||||
import org.jetbrains.kotlin.load.kotlin.loadModuleMapping
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.ModuleMapping
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
import org.jetbrains.kotlin.serialization.deserialization.DeserializationConfiguration
|
||||
@@ -45,11 +46,20 @@ class RuntimePackagePartProvider(private val classLoader: ClassLoader) : Package
|
||||
for (resource in resources) {
|
||||
try {
|
||||
resource.openStream()?.use { stream ->
|
||||
val mapping = ModuleMapping.loadModuleMapping(stream.readBytes(), resourcePath, DeserializationConfiguration.Default)
|
||||
val mapping = ModuleMapping.loadModuleMapping(
|
||||
stream.readBytes(), resourcePath, DeserializationConfiguration.Default
|
||||
) { version ->
|
||||
throw UnsupportedOperationException(
|
||||
"Module was compiled with an incompatible version of Kotlin. The binary version of its metadata is $version, " +
|
||||
"expected version is ${JvmMetadataVersion.INSTANCE}. Please update Kotlin to the latest version"
|
||||
)
|
||||
}
|
||||
for ((packageFqName, parts) in mapping.packageFqName2Parts) {
|
||||
packageParts.getOrPut(packageFqName) { linkedSetOf() }.addAll(parts.parts)
|
||||
}
|
||||
}
|
||||
} catch (e: UnsupportedOperationException) {
|
||||
throw e
|
||||
} catch (e: Exception) {
|
||||
// TODO: do not swallow this exception?
|
||||
}
|
||||
|
||||
+41
-40
@@ -33,7 +33,8 @@ class ModuleMapping private constructor(
|
||||
bytes: ByteArray?,
|
||||
debugName: String,
|
||||
skipMetadataVersionCheck: Boolean,
|
||||
isJvmPackageNameSupported: Boolean
|
||||
isJvmPackageNameSupported: Boolean,
|
||||
reportIncompatibleVersionError: (JvmMetadataVersion) -> Unit
|
||||
): ModuleMapping {
|
||||
if (bytes == null) {
|
||||
return EMPTY
|
||||
@@ -47,47 +48,47 @@ class ModuleMapping private constructor(
|
||||
return CORRUPTED
|
||||
}
|
||||
|
||||
if (skipMetadataVersionCheck || JvmMetadataVersion(*versionNumber).isCompatible()) {
|
||||
val moduleProto = JvmModuleProtoBuf.Module.parseFrom(stream) ?: return EMPTY
|
||||
val result = linkedMapOf<String, PackageParts>()
|
||||
|
||||
for (proto in moduleProto.packagePartsList) {
|
||||
val packageFqName = proto.packageFqName
|
||||
val packageParts = result.getOrPut(packageFqName) { PackageParts(packageFqName) }
|
||||
|
||||
for ((index, partShortName) in proto.shortClassNameList.withIndex()) {
|
||||
val multifileFacadeId = proto.multifileFacadeShortNameIdList.getOrNull(index)?.minus(1)
|
||||
val facadeShortName = multifileFacadeId?.let(proto.multifileFacadeShortNameList::getOrNull)
|
||||
val facadeInternalName = facadeShortName?.let { internalNameOf(packageFqName, it) }
|
||||
packageParts.addPart(internalNameOf(packageFqName, partShortName), facadeInternalName)
|
||||
}
|
||||
|
||||
if (isJvmPackageNameSupported) {
|
||||
for ((index, partShortName) in proto.classWithJvmPackageNameShortNameList.withIndex()) {
|
||||
val packageId = proto.classWithJvmPackageNamePackageIdList.getOrNull(index)
|
||||
?: proto.classWithJvmPackageNamePackageIdList.lastOrNull()
|
||||
?: continue
|
||||
val jvmPackageName = moduleProto.jvmPackageNameList.getOrNull(packageId) ?: continue
|
||||
packageParts.addPart(internalNameOf(jvmPackageName, partShortName), null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (proto in moduleProto.metadataPartsList) {
|
||||
val packageParts = result.getOrPut(proto.packageFqName) { PackageParts(proto.packageFqName) }
|
||||
proto.shortClassNameList.forEach(packageParts::addMetadataPart)
|
||||
}
|
||||
|
||||
// TODO: read arguments of module annotations
|
||||
val nameResolver = NameResolverImpl(moduleProto.stringTable, moduleProto.qualifiedNameTable)
|
||||
val annotations = moduleProto.annotationList.map { proto -> nameResolver.getQualifiedClassName(proto.id) }
|
||||
|
||||
return ModuleMapping(result, BinaryModuleData(annotations), debugName)
|
||||
} else {
|
||||
// TODO: consider reporting "incompatible ABI version" error for package parts
|
||||
val version = JvmMetadataVersion(*versionNumber)
|
||||
if (!skipMetadataVersionCheck && !version.isCompatible()) {
|
||||
reportIncompatibleVersionError(version)
|
||||
return EMPTY
|
||||
}
|
||||
|
||||
return EMPTY
|
||||
val moduleProto = JvmModuleProtoBuf.Module.parseFrom(stream) ?: return EMPTY
|
||||
val result = linkedMapOf<String, PackageParts>()
|
||||
|
||||
for (proto in moduleProto.packagePartsList) {
|
||||
val packageFqName = proto.packageFqName
|
||||
val packageParts = result.getOrPut(packageFqName) { PackageParts(packageFqName) }
|
||||
|
||||
for ((index, partShortName) in proto.shortClassNameList.withIndex()) {
|
||||
val multifileFacadeId = proto.multifileFacadeShortNameIdList.getOrNull(index)?.minus(1)
|
||||
val facadeShortName = multifileFacadeId?.let(proto.multifileFacadeShortNameList::getOrNull)
|
||||
val facadeInternalName = facadeShortName?.let { internalNameOf(packageFqName, it) }
|
||||
packageParts.addPart(internalNameOf(packageFqName, partShortName), facadeInternalName)
|
||||
}
|
||||
|
||||
if (isJvmPackageNameSupported) {
|
||||
for ((index, partShortName) in proto.classWithJvmPackageNameShortNameList.withIndex()) {
|
||||
val packageId = proto.classWithJvmPackageNamePackageIdList.getOrNull(index)
|
||||
?: proto.classWithJvmPackageNamePackageIdList.lastOrNull()
|
||||
?: continue
|
||||
val jvmPackageName = moduleProto.jvmPackageNameList.getOrNull(packageId) ?: continue
|
||||
packageParts.addPart(internalNameOf(jvmPackageName, partShortName), null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (proto in moduleProto.metadataPartsList) {
|
||||
val packageParts = result.getOrPut(proto.packageFqName) { PackageParts(proto.packageFqName) }
|
||||
proto.shortClassNameList.forEach(packageParts::addMetadataPart)
|
||||
}
|
||||
|
||||
// TODO: read arguments of module annotations
|
||||
val nameResolver = NameResolverImpl(moduleProto.stringTable, moduleProto.qualifiedNameTable)
|
||||
val annotations = moduleProto.annotationList.map { proto -> nameResolver.getQualifiedClassName(proto.id) }
|
||||
|
||||
return ModuleMapping(result, BinaryModuleData(annotations), debugName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user