Use internal names in multifile class metadata
To reuse the strings already existing in the constant pool of the class file
This commit is contained in:
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.codegen.context.MethodContext
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.config.IncrementalCompilation
|
import org.jetbrains.kotlin.config.IncrementalCompilation
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
@@ -57,7 +56,6 @@ import org.jetbrains.org.objectweb.asm.Type
|
|||||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|
||||||
public class MultifileClassCodegen(
|
public class MultifileClassCodegen(
|
||||||
private val state: GenerationState,
|
private val state: GenerationState,
|
||||||
public val files: Collection<JetFile>,
|
public val files: Collection<JetFile>,
|
||||||
@@ -200,7 +198,7 @@ public class MultifileClassCodegen(
|
|||||||
|
|
||||||
val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment, facadeFqName), partType, file)
|
val builder = state.factory.newVisitor(MultifileClassPart(file, packageFragment, facadeFqName), partType, file)
|
||||||
|
|
||||||
MultifileClassPartCodegen(builder, file, partType, facadeFqName, partContext, state).generate()
|
MultifileClassPartCodegen(builder, file, partType, facadeClassType, partContext, state).generate()
|
||||||
|
|
||||||
val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType)
|
val facadeContext = state.rootContext.intoMultifileClass(packageFragment, facadeClassType, partType)
|
||||||
val memberCodegen = createCodegenForPartOfMultifileFacade(facadeContext)
|
val memberCodegen = createCodegenForPartOfMultifileFacade(facadeContext)
|
||||||
@@ -280,12 +278,12 @@ public class MultifileClassCodegen(
|
|||||||
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
|
val av = classBuilder.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS), true)
|
||||||
JvmCodegenUtil.writeAbiVersion(av)
|
JvmCodegenUtil.writeAbiVersion(av)
|
||||||
|
|
||||||
val shortNames = partFqNames.map { it.shortName().asString() }.sorted()
|
val partInternalNames = partFqNames.map { JvmClassName.byFqNameWithoutInnerClasses(it).internalName }.sorted()
|
||||||
val filePartClassNamesArray = av.visitArray(JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
|
val arv = av.visitArray(JvmAnnotationNames.FILE_PART_CLASS_NAMES_FIELD_NAME)
|
||||||
for (shortName in shortNames) {
|
for (internalName in partInternalNames) {
|
||||||
filePartClassNamesArray.visit(null, shortName)
|
arv.visit(null, internalName)
|
||||||
}
|
}
|
||||||
filePartClassNamesArray.visitEnd()
|
arv.visitEnd()
|
||||||
|
|
||||||
av.visitEnd()
|
av.visitEnd()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ import org.jetbrains.kotlin.codegen.serialization.JvmSerializerExtension
|
|||||||
import org.jetbrains.kotlin.codegen.state.GenerationState
|
import org.jetbrains.kotlin.codegen.state.GenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||||
import org.jetbrains.kotlin.name.FqName
|
|
||||||
import org.jetbrains.kotlin.psi.JetFile
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.psi.JetNamedFunction
|
import org.jetbrains.kotlin.psi.JetNamedFunction
|
||||||
import org.jetbrains.kotlin.psi.JetProperty
|
import org.jetbrains.kotlin.psi.JetProperty
|
||||||
@@ -36,7 +35,7 @@ public class MultifileClassPartCodegen(
|
|||||||
v: ClassBuilder,
|
v: ClassBuilder,
|
||||||
file: JetFile,
|
file: JetFile,
|
||||||
private val filePartType: Type,
|
private val filePartType: Type,
|
||||||
private val multifileClassFqName: FqName,
|
private val multifileClassType: Type,
|
||||||
partContext: FieldOwnerContext<*>,
|
partContext: FieldOwnerContext<*>,
|
||||||
state: GenerationState
|
state: GenerationState
|
||||||
) : MemberCodegen<JetFile>(state, null, partContext, file, v) {
|
) : MemberCodegen<JetFile>(state, null, partContext, file, v) {
|
||||||
@@ -97,7 +96,7 @@ public class MultifileClassPartCodegen(
|
|||||||
|
|
||||||
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS_PART), true)
|
val av = v.newAnnotation(AsmUtil.asmDescByFqNameWithoutInnerClasses(JvmAnnotationNames.KOTLIN_MULTIFILE_CLASS_PART), true)
|
||||||
AsmUtil.writeAnnotationData(av, serializer, packageProto)
|
AsmUtil.writeAnnotationData(av, serializer, packageProto)
|
||||||
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassFqName.shortName().asString())
|
av.visit(JvmAnnotationNames.MULTIFILE_CLASS_NAME_FIELD_NAME, multifileClassType.internalName)
|
||||||
av.visitEnd()
|
av.visitEnd()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -61,7 +61,7 @@ public class LazyJavaPackageScope(
|
|||||||
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
KotlinClassHeader.Kind.MULTIFILE_CLASS_PART -> {
|
||||||
val partName = kotlinClass.classId.shortClassName.asString()
|
val partName = kotlinClass.classId.shortClassName.asString()
|
||||||
val facadeName = header.multifileClassName ?: continue@kotlinClasses
|
val facadeName = header.multifileClassName ?: continue@kotlinClasses
|
||||||
result[partName] = facadeName
|
result[partName] = facadeName.substringAfterLast('/')
|
||||||
}
|
}
|
||||||
KotlinClassHeader.Kind.FILE_FACADE -> {
|
KotlinClassHeader.Kind.FILE_FACADE -> {
|
||||||
val fileFacadeName = kotlinClass.classId.shortClassName.asString()
|
val fileFacadeName = kotlinClass.classId.shortClassName.asString()
|
||||||
|
|||||||
@@ -89,9 +89,6 @@ public fun findMultifileClassParts(file: VirtualFile, multifileClass: KotlinJvmB
|
|||||||
val partsFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName)
|
val partsFinder = DirectoryBasedClassFinder(file.parent!!, packageFqName)
|
||||||
val partNames = multifileClass.classHeader.filePartClassNames ?: return emptyList()
|
val partNames = multifileClass.classHeader.filePartClassNames ?: return emptyList()
|
||||||
return partNames.map {
|
return partNames.map {
|
||||||
partsFinder.findKotlinClass(ClassId(packageFqName, Name.identifier(it)))
|
partsFinder.findKotlinClass(ClassId(packageFqName, Name.identifier(it.substringAfterLast('/'))))
|
||||||
}.filterNotNull()
|
}.filterNotNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun readMultifileClassPartHeaders(file: VirtualFile, multifileClass: KotlinJvmBinaryClass): List<KotlinClassHeader> =
|
|
||||||
findMultifileClassParts(file, multifileClass).map { it.classHeader }
|
|
||||||
|
|||||||
+1
-1
@@ -80,7 +80,7 @@ fun createMultifileClassStub(
|
|||||||
components: ClsStubBuilderComponents
|
components: ClsStubBuilderComponents
|
||||||
): KotlinFileStubImpl {
|
): KotlinFileStubImpl {
|
||||||
val packageFqName = facadeFqName.parent()
|
val packageFqName = facadeFqName.parent()
|
||||||
val partNames = multifileClass.classHeader.filePartClassNames?.asList()
|
val partNames = multifileClass.classHeader.filePartClassNames?.asList()?.map { it.substringAfterLast('/') }
|
||||||
val fileStub = KotlinFileStubForIde.forMultifileClassStub(facadeFqName, partNames, packageFqName.isRoot)
|
val fileStub = KotlinFileStubForIde.forMultifileClassStub(facadeFqName, partNames, packageFqName.isRoot)
|
||||||
setupFileStub(fileStub, packageFqName)
|
setupFileStub(fileStub, packageFqName)
|
||||||
for (partFile in partFiles) {
|
for (partFile in partFiles) {
|
||||||
|
|||||||
@@ -198,7 +198,8 @@ public class IncrementalCacheImpl(
|
|||||||
inlineFunctionsMap.process(kotlinClass)
|
inlineFunctionsMap.process(kotlinClass)
|
||||||
}
|
}
|
||||||
header.isCompatibleMultifileClassKind() -> {
|
header.isCompatibleMultifileClassKind() -> {
|
||||||
val partNames = getFullNamesOfMultifileClassParts(kotlinClass)
|
val partNames = kotlinClass.classHeader.filePartClassNames?.toList()
|
||||||
|
?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
|
||||||
multifileClassFacadeMap.add(className, partNames)
|
multifileClassFacadeMap.add(className, partNames)
|
||||||
|
|
||||||
// TODO NO_CHANGES? (delegates only, see package facade)
|
// TODO NO_CHANGES? (delegates only, see package facade)
|
||||||
@@ -208,8 +209,7 @@ public class IncrementalCacheImpl(
|
|||||||
header.isCompatibleMultifileClassPartKind() -> {
|
header.isCompatibleMultifileClassPartKind() -> {
|
||||||
assert(sourceFiles.size() == 1) { "Multifile class part from several source files: $sourceFiles" }
|
assert(sourceFiles.size() == 1) { "Multifile class part from several source files: $sourceFiles" }
|
||||||
packagePartMap.addPackagePart(className)
|
packagePartMap.addPackagePart(className)
|
||||||
val facadeClassName = getInternalNameOfTopLevelClassInTheSamePackage(kotlinClass, header.multifileClassName!!)
|
multifileClassPartMap.add(className.internalName, header.multifileClassName!!)
|
||||||
multifileClassPartMap.add(className.internalName, facadeClassName)
|
|
||||||
|
|
||||||
protoMap.process(kotlinClass, isPackage = true) +
|
protoMap.process(kotlinClass, isPackage = true) +
|
||||||
constantsMap.process(kotlinClass) +
|
constantsMap.process(kotlinClass) +
|
||||||
@@ -698,21 +698,6 @@ private fun ByteArray.md5(): Long {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getInternalNameOfTopLevelClassInTheSamePackage(kotlinClass: KotlinJvmBinaryClass, simpleName: String): String {
|
|
||||||
val classFqName = kotlinClass.classId.packageFqName.child(Name.identifier(simpleName))
|
|
||||||
return JvmClassName.byFqNameWithoutInnerClasses(classFqName).internalName
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun getFullNamesOfMultifileClassParts(kotlinClass: LocalFileKotlinClass): List<String> {
|
|
||||||
val classHeader = kotlinClass.classHeader
|
|
||||||
val partClassNames = classHeader.filePartClassNames ?: throw AssertionError("Multifile class has no parts: ${kotlinClass.className}")
|
|
||||||
val fullNames = arrayListOf<String>()
|
|
||||||
for (shortName in partClassNames) {
|
|
||||||
fullNames.add(getInternalNameOfTopLevelClassInTheSamePackage(kotlinClass, shortName))
|
|
||||||
}
|
|
||||||
return fullNames
|
|
||||||
}
|
|
||||||
|
|
||||||
private abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
private abstract class StringMapExternalizer<T> : DataExternalizer<Map<String, T>> {
|
||||||
override fun save(out: DataOutput, map: Map<String, T>?) {
|
override fun save(out: DataOutput, map: Map<String, T>?) {
|
||||||
out.writeInt(map!!.size())
|
out.writeInt(map!!.size())
|
||||||
|
|||||||
Reference in New Issue
Block a user