Support free-form .knm package part names

This commit is contained in:
Simon Ogorodnik
2018-09-11 20:19:47 +03:00
parent 7166c011bf
commit ca742b1552
8 changed files with 32 additions and 17 deletions
@@ -105,9 +105,9 @@ internal object CachingIdeMetadataReaderImpl : MetadataReader {
override fun loadSerializedPackageFragment( override fun loadSerializedPackageFragment(
libraryLayout: KonanLibraryLayout, libraryLayout: KonanLibraryLayout,
packageFqName: String, packageFqName: String,
partIndex: Int partName: String
): KonanProtoBuf.LinkDataPackageFragment = ): KonanProtoBuf.LinkDataPackageFragment =
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName, partIndex))) cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName, partName)))
private fun KonanLibraryLayout.getVirtualFile(file: File): VirtualFile { private fun KonanLibraryLayout.getVirtualFile(file: File): VirtualFile {
val source = this.source val source = this.source
@@ -44,8 +44,8 @@ interface KonanLibrary {
val dataFlowGraph: ByteArray? val dataFlowGraph: ByteArray?
val moduleHeaderData: KonanProtoBuf.LinkDataLibrary val moduleHeaderData: KonanProtoBuf.LinkDataLibrary
fun packageMetadataPartCount(fqName: String): Int fun packageMetadataParts(fqName: String): Set<String>
fun packageMetadata(packageFqName: String, partIndex: Int): KonanProtoBuf.LinkDataPackageFragment fun packageMetadata(packageFqName: String, partName: String): KonanProtoBuf.LinkDataPackageFragment
} }
val KonanLibrary.uniqueName val KonanLibrary.uniqueName
@@ -38,8 +38,8 @@ interface KonanLibraryLayout {
fun packageFragmentsDir(packageFqName: String) = fun packageFragmentsDir(packageFqName: String) =
File(linkdataDir, if (packageFqName == "") "root_package" else "package_$packageFqName") File(linkdataDir, if (packageFqName == "") "root_package" else "package_$packageFqName")
fun packageFragmentFile(packageFqName: String, partIndex: Int) = fun packageFragmentFile(packageFqName: String, partName: String) =
File(packageFragmentsDir(packageFqName), "$partIndex$KLIB_METADATA_FILE_EXTENSION_WITH_DOT") File(packageFragmentsDir(packageFqName), "$partName$KLIB_METADATA_FILE_EXTENSION_WITH_DOT")
} }
sealed class KonanLibrarySource { sealed class KonanLibrarySource {
@@ -12,6 +12,6 @@ interface MetadataReader {
fun loadSerializedPackageFragment( fun loadSerializedPackageFragment(
libraryLayout: KonanLibraryLayout, libraryLayout: KonanLibraryLayout,
packageFqName: String, packageFqName: String,
partIndex: Int partName: String
): KonanProtoBuf.LinkDataPackageFragment ): KonanProtoBuf.LinkDataPackageFragment
} }
@@ -19,9 +19,9 @@ object DefaultMetadataReaderImpl : MetadataReader {
override fun loadSerializedPackageFragment( override fun loadSerializedPackageFragment(
libraryLayout: KonanLibraryLayout, libraryLayout: KonanLibraryLayout,
packageFqName: String, packageFqName: String,
partIndex: Int partName: String
): KonanProtoBuf.LinkDataPackageFragment = ): KonanProtoBuf.LinkDataPackageFragment =
parsePackageFragment( parsePackageFragment(
libraryLayout.packageFragmentFile(packageFqName, partIndex).readBytes() libraryLayout.packageFragmentFile(packageFqName, partName).readBytes()
) )
} }
@@ -62,10 +62,25 @@ internal class KonanLibraryImpl(
override val moduleHeaderData: KonanProtoBuf.LinkDataLibrary by lazy { layout.inPlace { metadataReader.loadSerializedModule(it) } } override val moduleHeaderData: KonanProtoBuf.LinkDataLibrary by lazy { layout.inPlace { metadataReader.loadSerializedModule(it) } }
override fun packageMetadata(packageFqName: String, partIndex: Int) = layout.inPlace { metadataReader.loadSerializedPackageFragment(it, packageFqName, partIndex) } override fun packageMetadata(packageFqName: String, partName: String) =
layout.inPlace { metadataReader.loadSerializedPackageFragment(it, packageFqName, partName) }
override fun packageMetadataParts(fqName: String): Set<String> =
layout.inPlace { inPlaceLayout ->
val fileList =
inPlaceLayout.packageFragmentsDir(fqName)
.listFiles
.mapNotNull {
it.name
.substringBeforeLast(KLIB_METADATA_FILE_EXTENSION_WITH_DOT, missingDelimiterValue = "")
.takeIf { it.isNotEmpty() }
}
fileList.toSortedSet().also {
require(it.size == fileList.size) { "Duplicated names: ${fileList.groupingBy { it }.eachCount().filter { (_, count) -> count > 1 }}" }
}
}
override fun packageMetadataPartCount(fqName: String): Int =
layout.inPlace { it.packageFragmentsDir(fqName).listFiles.count { file -> file.extension == KLIB_METADATA_FILE_EXTENSION } }
override fun toString() = "$libraryName[default=$isDefault]" override fun toString() = "$libraryName[default=$isDefault]"
} }
@@ -25,7 +25,7 @@ class KonanPackageFragment(
private val packageAccessedHandler: PackageAccessedHandler?, private val packageAccessedHandler: PackageAccessedHandler?,
storageManager: StorageManager, storageManager: StorageManager,
module: ModuleDescriptor, module: ModuleDescriptor,
partIndex: Int partName: String
) : DeserializedPackageFragment(fqName, storageManager, module) { ) : DeserializedPackageFragment(fqName, storageManager, module) {
lateinit var components: DeserializationComponents lateinit var components: DeserializationComponents
@@ -36,7 +36,7 @@ class KonanPackageFragment(
// The proto field is lazy so that we can load only needed // The proto field is lazy so that we can load only needed
// packages from the library. // packages from the library.
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString(), partIndex) } private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString(), partName) }
val proto: KonanProtoBuf.LinkDataPackageFragment val proto: KonanProtoBuf.LinkDataPackageFragment
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName) } get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName) }
@@ -38,9 +38,9 @@ internal object KonanDeserializedPackageFragmentsFactoryImpl : KonanDeserialized
storageManager: StorageManager storageManager: StorageManager
) = packageFragmentNames.flatMap { ) = packageFragmentNames.flatMap {
val fqName = FqName(it) val fqName = FqName(it)
val count = library.packageMetadataPartCount(fqName.asString()) val parts = library.packageMetadataParts(it)
List(count) { partIndex -> parts.map { partName ->
KonanPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partIndex) KonanPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partName)
} }
} }