JVM IR: generate correct metadata for multi-file classes

This commit is contained in:
Alexander Udalov
2019-07-23 13:54:43 +02:00
parent 4be0e00071
commit f01b0f6467
9 changed files with 55 additions and 27 deletions
@@ -65,6 +65,7 @@ class JvmBackendContext(
internal val localDelegatedProperties = mutableMapOf<IrClass, List<IrLocalDelegatedPropertySymbol>>()
internal val multifileFacadesToAdd = mutableMapOf<JvmClassName, MutableList<IrClass>>()
internal val multifileFacadeForPart = mutableMapOf<IrClass, JvmClassName>()
override var inVerbosePhase: Boolean = false
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
@@ -144,13 +145,31 @@ open class ClassCodegen protected constructor(
serializerExtension.serializeJvmPackage(packageProto, type)
writeKotlinMetadata(visitor, state, KotlinClassHeader.Kind.FILE_FACADE, 0) {
AsmUtil.writeAnnotationData(it, serializer, packageProto.build())
val facadeClassName = context.multifileFacadeForPart[irClass.attributeOwnerId]
val kind = if (facadeClassName != null) KotlinClassHeader.Kind.MULTIFILE_CLASS_PART else KotlinClassHeader.Kind.FILE_FACADE
writeKotlinMetadata(visitor, state, kind, 0) { av ->
AsmUtil.writeAnnotationData(av, serializer, packageProto.build())
if (facadeClassName != null) {
av.visit(JvmAnnotationNames.METADATA_MULTIFILE_CLASS_NAME_FIELD_NAME, facadeClassName.internalName)
}
// TODO: JvmPackageName
}
}
else -> {
writeSyntheticClassMetadata(visitor, state)
val entry = irClass.fileParent.fileEntry
if (entry is MultifileFacadeFileEntry) {
val partInternalNames = entry.partFiles.mapNotNull { partFile ->
val fileClass = partFile.declarations.singleOrNull { it.origin == IrDeclarationOrigin.FILE_CLASS } as IrClass?
if (fileClass != null) typeMapper.mapClass(fileClass).internalName else null
}
MultifileClassCodegenImpl.writeMetadata(
visitor, state, 0 /* TODO */, partInternalNames, type, irClass.fqNameWhenAvailable!!.parent()
)
} else {
writeSyntheticClassMetadata(visitor, state)
}
}
}
}
@@ -85,6 +85,8 @@ private fun generateMultifileFacades(module: ModuleDescriptor, context: JvmBacke
file.declarations.add(facadeClass)
for (partClass in partClasses) {
context.multifileFacadeForPart[partClass.attributeOwnerId as IrClass] = jvmClassName
for (member in partClass.declarations) {
member.createMultifileDelegateIfNeeded(context, facadeClass)
}