Support for split-packages in Kotlin Native
See JetBrains/kotlin-native#2034
This commit is contained in:
@@ -23,13 +23,13 @@ import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||
import org.jetbrains.kotlin.idea.caches.project.LibraryInfo
|
||||
import org.jetbrains.kotlin.idea.decompiler.textBuilder.LoggingErrorReporter
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultPackageFragmentsFactory
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryDir
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrarySource.KonanLibraryFile
|
||||
import org.jetbrains.kotlin.konan.library.MetadataReader
|
||||
import org.jetbrains.kotlin.konan.library.createKonanLibrary
|
||||
import org.jetbrains.kotlin.konan.util.KonanFactories.DefaultPackageFragmentsFactory
|
||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
@@ -104,9 +104,10 @@ internal object CachingIdeMetadataReaderImpl : MetadataReader {
|
||||
|
||||
override fun loadSerializedPackageFragment(
|
||||
libraryLayout: KonanLibraryLayout,
|
||||
packageFqName: String
|
||||
packageFqName: String,
|
||||
partIndex: Int
|
||||
): KonanProtoBuf.LinkDataPackageFragment =
|
||||
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName)))
|
||||
cache.getCachedPackageFragment(libraryLayout.getVirtualFile(libraryLayout.packageFragmentFile(packageFqName, partIndex)))
|
||||
|
||||
private fun KonanLibraryLayout.getVirtualFile(file: File): VirtualFile {
|
||||
val source = this.source
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
package org.jetbrains.kotlin.ide.konan
|
||||
|
||||
import com.intellij.openapi.roots.libraries.PersistentLibraryKind
|
||||
import com.intellij.openapi.vfs.VfsUtil
|
||||
import com.intellij.openapi.vfs.VirtualFile
|
||||
import com.intellij.openapi.vfs.VirtualFileManager
|
||||
import com.intellij.openapi.vfs.VirtualFileVisitor
|
||||
import org.jetbrains.kotlin.builtins.DefaultBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.caches.resolve.IdePlatformKindResolution
|
||||
@@ -29,8 +32,11 @@ class NativePlatformKindResolution : IdePlatformKindResolution {
|
||||
|
||||
override fun isLibraryFileForPlatform(virtualFile: VirtualFile): Boolean {
|
||||
return if (virtualFile.isDirectory) {
|
||||
virtualFile.findChild("linkdata")?.takeIf { it.isDirectory }
|
||||
?.children?.any { it.extension == KLIB_METADATA_FILE_EXTENSION } == true
|
||||
val dir = virtualFile.findChild("linkdata") ?: return false
|
||||
// False means we hit .knm file
|
||||
!VfsUtil.processFilesRecursively(dir) {
|
||||
it.extension != KLIB_METADATA_FILE_EXTENSION
|
||||
}
|
||||
} else {
|
||||
virtualFile.extension == KLIB_FILE_EXTENSION
|
||||
}
|
||||
|
||||
+2
-2
@@ -101,10 +101,10 @@ sealed class FileWithMetadata {
|
||||
|
||||
open class Compatible(
|
||||
val proto: KonanProtoBuf.LinkDataPackageFragment,
|
||||
serializerProtocol: SerializerExtensionProtocol
|
||||
serializerProtocol: SerializerExtensionProtocol // TODO: Is it required?
|
||||
) : FileWithMetadata() {
|
||||
val nameResolver = NameResolverImpl(proto.stringTable, proto.nameTable)
|
||||
val packageFqName = FqName(nameResolver.getPackageFqName(proto.`package`.getExtension(serializerProtocol.packageFqName)))
|
||||
val packageFqName = FqName(proto.fqName)
|
||||
|
||||
open val classesToDecompile: List<ProtoBuf.Class> =
|
||||
proto.classes.classesList.filter { proto ->
|
||||
|
||||
@@ -44,7 +44,8 @@ interface KonanLibrary {
|
||||
|
||||
val dataFlowGraph: ByteArray?
|
||||
val moduleHeaderData: KonanProtoBuf.LinkDataLibrary
|
||||
fun packageMetadata(packageFqName: String): KonanProtoBuf.LinkDataPackageFragment
|
||||
fun packageMetadataPartCount(fqName: String): Int
|
||||
fun packageMetadata(packageFqName: String, partIndex: Int): KonanProtoBuf.LinkDataPackageFragment
|
||||
}
|
||||
|
||||
val KonanLibrary.uniqueName
|
||||
|
||||
@@ -35,11 +35,11 @@ interface KonanLibraryLayout {
|
||||
val moduleHeaderFile get() = File(linkdataDir, KLIB_MODULE_METADATA_FILE_NAME)
|
||||
val dataFlowGraphFile get() = File(linkdataDir, "module_data_flow_graph")
|
||||
|
||||
fun packageFragmentFile(packageFqName: String) =
|
||||
File(
|
||||
linkdataDir,
|
||||
if (packageFqName == "") "root_package.$KLIB_METADATA_FILE_EXTENSION" else "package_$packageFqName.$KLIB_METADATA_FILE_EXTENSION"
|
||||
)
|
||||
fun packageFragmentsDir(packageFqName: String) =
|
||||
File(linkdataDir, if (packageFqName == "") "root_package" else "package_$packageFqName")
|
||||
|
||||
fun packageFragmentFile(packageFqName: String, partIndex: Int) =
|
||||
File(packageFragmentsDir(packageFqName), "$partIndex$KLIB_METADATA_FILE_EXTENSION_WITH_DOT")
|
||||
}
|
||||
|
||||
sealed class KonanLibrarySource {
|
||||
|
||||
@@ -9,5 +9,9 @@ import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
|
||||
interface MetadataReader {
|
||||
fun loadSerializedModule(libraryLayout: KonanLibraryLayout): KonanProtoBuf.LinkDataLibrary
|
||||
fun loadSerializedPackageFragment(libraryLayout: KonanLibraryLayout, packageFqName: String): KonanProtoBuf.LinkDataPackageFragment
|
||||
fun loadSerializedPackageFragment(
|
||||
libraryLayout: KonanLibraryLayout,
|
||||
packageFqName: String,
|
||||
partIndex: Int
|
||||
): KonanProtoBuf.LinkDataPackageFragment
|
||||
}
|
||||
|
||||
+5
-2
@@ -18,7 +18,10 @@ object DefaultMetadataReaderImpl : MetadataReader {
|
||||
|
||||
override fun loadSerializedPackageFragment(
|
||||
libraryLayout: KonanLibraryLayout,
|
||||
packageFqName: String
|
||||
packageFqName: String,
|
||||
partIndex: Int
|
||||
): KonanProtoBuf.LinkDataPackageFragment =
|
||||
parsePackageFragment(libraryLayout.packageFragmentFile(packageFqName).readBytes())
|
||||
parsePackageFragment(
|
||||
libraryLayout.packageFragmentFile(packageFqName, partIndex).readBytes()
|
||||
)
|
||||
}
|
||||
|
||||
+5
-5
@@ -6,10 +6,7 @@
|
||||
package org.jetbrains.kotlin.konan.library.impl
|
||||
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.library.KLIB_PROPERTY_ABI_VERSION
|
||||
import org.jetbrains.kotlin.konan.library.KLIB_PROPERTY_LINKED_OPTS
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.MetadataReader
|
||||
import org.jetbrains.kotlin.konan.library.*
|
||||
import org.jetbrains.kotlin.konan.properties.Properties
|
||||
import org.jetbrains.kotlin.konan.properties.loadProperties
|
||||
import org.jetbrains.kotlin.konan.properties.propertyList
|
||||
@@ -65,7 +62,10 @@ internal class KonanLibraryImpl(
|
||||
|
||||
override val moduleHeaderData: KonanProtoBuf.LinkDataLibrary by lazy { layout.inPlace { metadataReader.loadSerializedModule(it) } }
|
||||
|
||||
override fun packageMetadata(packageFqName: String) = layout.inPlace { metadataReader.loadSerializedPackageFragment(it, packageFqName) }
|
||||
override fun packageMetadata(packageFqName: String, partIndex: Int) = layout.inPlace { metadataReader.loadSerializedPackageFragment(it, packageFqName, partIndex) }
|
||||
|
||||
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]"
|
||||
}
|
||||
|
||||
+3
-2
@@ -24,7 +24,8 @@ class KonanPackageFragment(
|
||||
private val library: KonanLibrary,
|
||||
private val packageAccessedHandler: PackageAccessedHandler?,
|
||||
storageManager: StorageManager,
|
||||
module: ModuleDescriptor
|
||||
module: ModuleDescriptor,
|
||||
partIndex: Int
|
||||
) : DeserializedPackageFragment(fqName, storageManager, module) {
|
||||
|
||||
lateinit var components: DeserializationComponents
|
||||
@@ -35,7 +36,7 @@ class KonanPackageFragment(
|
||||
|
||||
// The proto field is lazy so that we can load only needed
|
||||
// packages from the library.
|
||||
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString()) }
|
||||
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy { library.packageMetadata(fqName.asString(), partIndex) }
|
||||
|
||||
val proto: KonanProtoBuf.LinkDataPackageFragment
|
||||
get() = protoForNames.also { packageAccessedHandler?.markPackageAccessed(fqName) }
|
||||
|
||||
+6
-2
@@ -36,8 +36,12 @@ internal object KonanDeserializedPackageFragmentsFactoryImpl : KonanDeserialized
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
packageAccessedHandler: PackageAccessedHandler?,
|
||||
storageManager: StorageManager
|
||||
) = packageFragmentNames.map {
|
||||
KonanPackageFragment(FqName(it), library, packageAccessedHandler, storageManager, moduleDescriptor)
|
||||
) = packageFragmentNames.flatMap {
|
||||
val fqName = FqName(it)
|
||||
val count = library.packageMetadataPartCount(fqName.asString())
|
||||
List(count) { partIndex ->
|
||||
KonanPackageFragment(fqName, library, packageAccessedHandler, storageManager, moduleDescriptor, partIndex)
|
||||
}
|
||||
}
|
||||
|
||||
override fun createSyntheticPackageFragments(
|
||||
|
||||
Reference in New Issue
Block a user