diff --git a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt index 5ff6fe2fa4e..20c5cbba1e6 100644 --- a/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt +++ b/compiler/backend/src/org/jetbrains/kotlin/codegen/MultifileClassCodegen.kt @@ -307,27 +307,17 @@ class MultifileClassCodegenImpl( val extraFlags = if (shouldGeneratePartHierarchy) JvmAnnotationNames.METADATA_MULTIFILE_PARTS_INHERIT_FLAG else 0 - writeKotlinMetadata(classBuilder, state, KotlinClassHeader.Kind.MULTIFILE_CLASS, extraFlags) { av -> - val arv = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME) - for (internalName in partInternalNamesSorted) { - arv.visit(null, internalName) - } - arv.visitEnd() + val kotlinPackageFqName = + packageFragment?.fqName ?: compiledPackageFragment?.fqName + ?: error("Either source package or compiled package should not be null: $facadeClassType ($files)") - val kotlinPackageFqName = - packageFragment?.fqName ?: compiledPackageFragment?.fqName - ?: error("Either source package or compiled package should not be null: $facadeClassType ($files)") + if (files.any { it.packageFqName != kotlinPackageFqName }) + throw UnsupportedOperationException( + "Multi-file parts of a facade with JvmPackageName should all lie in the same Kotlin package:\n " + + files.joinToString("\n ") { file -> "$file: package ${file.packageFqName}" } + ) - if (files.any { it.packageFqName != kotlinPackageFqName }) - throw UnsupportedOperationException( - "Multi-file parts of a facade with JvmPackageName should all lie in the same Kotlin package:\n " + - files.joinToString("\n ") { file -> "$file: package ${file.packageFqName}" } - ) - - if (kotlinPackageFqName != JvmClassName.byInternalName(facadeClassType.internalName).packageFqName) { - av.visit(JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME, kotlinPackageFqName.asString()) - } - } + writeMetadata(classBuilder, state, extraFlags, partInternalNamesSorted, facadeClassType, kotlinPackageFqName) } private fun createCodegenForDelegatesInMultifileFacade(facadeContext: FieldOwnerContext<*>): MemberCodegen = @@ -375,5 +365,26 @@ class MultifileClassCodegenImpl( return incrementalPackageFragment?.getPackageFragmentForMultifileClass(facadeFqName) } + + fun writeMetadata( + classBuilder: ClassBuilder, + state: GenerationState, + flags: Int, + partInternalNames: List, + facadeClassType: Type, + kotlinPackageFqName: FqName + ) { + writeKotlinMetadata(classBuilder, state, KotlinClassHeader.Kind.MULTIFILE_CLASS, flags) { av -> + val arv = av.visitArray(JvmAnnotationNames.METADATA_DATA_FIELD_NAME) + for (internalName in partInternalNames) { + arv.visit(null, internalName) + } + arv.visitEnd() + + if (kotlinPackageFqName != JvmClassName.byInternalName(facadeClassType.internalName).packageFqName) { + av.visit(JvmAnnotationNames.METADATA_PACKAGE_NAME_FIELD_NAME, kotlinPackageFqName.asString()) + } + } + } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 57b7e1d3938..d2a5e868420 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -65,6 +65,7 @@ class JvmBackendContext( internal val localDelegatedProperties = mutableMapOf>() internal val multifileFacadesToAdd = mutableMapOf>() + internal val multifileFacadeForPart = mutableMapOf() override var inVerbosePhase: Boolean = false diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt index beeebf479a9..1c6e1a018fe 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ClassCodegen.kt @@ -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) + } } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt index 605c94c72d1..907a85eecf8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/GenerateMultifileFacades.kt @@ -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) } diff --git a/jps-plugin/testData/incremental/withJava/other/multifileClassAddTopLevelFunWithDefault/directives.txt b/jps-plugin/testData/incremental/withJava/other/multifileClassAddTopLevelFunWithDefault/directives.txt deleted file mode 100644 index 5099b2ad971..00000000000 --- a/jps-plugin/testData/incremental/withJava/other/multifileClassAddTopLevelFunWithDefault/directives.txt +++ /dev/null @@ -1 +0,0 @@ -// IGNORE_BACKEND: JVM_IR diff --git a/jps-plugin/testData/incremental/withJava/other/multifileClassFileAdded/directives.txt b/jps-plugin/testData/incremental/withJava/other/multifileClassFileAdded/directives.txt deleted file mode 100644 index 5099b2ad971..00000000000 --- a/jps-plugin/testData/incremental/withJava/other/multifileClassFileAdded/directives.txt +++ /dev/null @@ -1 +0,0 @@ -// IGNORE_BACKEND: JVM_IR diff --git a/jps-plugin/testData/incremental/withJava/other/multifileClassFileChanged/directives.txt b/jps-plugin/testData/incremental/withJava/other/multifileClassFileChanged/directives.txt deleted file mode 100644 index 5099b2ad971..00000000000 --- a/jps-plugin/testData/incremental/withJava/other/multifileClassFileChanged/directives.txt +++ /dev/null @@ -1 +0,0 @@ -// IGNORE_BACKEND: JVM_IR diff --git a/jps-plugin/testData/incremental/withJava/other/multifilePackagePartMethodAdded/directives.txt b/jps-plugin/testData/incremental/withJava/other/multifilePackagePartMethodAdded/directives.txt deleted file mode 100644 index 5099b2ad971..00000000000 --- a/jps-plugin/testData/incremental/withJava/other/multifilePackagePartMethodAdded/directives.txt +++ /dev/null @@ -1 +0,0 @@ -// IGNORE_BACKEND: JVM_IR diff --git a/jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties/directives.txt b/jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties/directives.txt deleted file mode 100644 index 5099b2ad971..00000000000 --- a/jps-plugin/testData/incremental/withJava/other/multifilePartsWithProperties/directives.txt +++ /dev/null @@ -1 +0,0 @@ -// IGNORE_BACKEND: JVM_IR