KLIB reader: better isolation of implementation details (#1917)

KLIB reader:
- better isolation of implementation details
- rename entities closer to their meaning: KonanLibrary -> KonanLibraryLayout, KonanLibraryReader -> KonanLibrary
This commit is contained in:
Dmitriy Dolovov
2018-08-23 10:46:58 +03:00
committed by GitHub
parent a216bf8903
commit 314cd0993b
21 changed files with 391 additions and 329 deletions
@@ -1,44 +1,64 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.name.FqName
// This scheme describes the Kotlin/Native Library (klib) layout.
interface KonanLibraryLayout {
const val KLIB_PROPERTY_ABI_VERSION = "abi_version"
const val KLIB_PROPERTY_UNIQUE_NAME = "unique_name"
const val KLIB_PROPERTY_LINKED_OPTS = "linkerOpts"
const val KLIB_PROPERTY_DEPENDS = "depends"
const val KLIB_PROPERTY_INTEROP = "interop"
const val KLIB_PROPERTY_PACKAGE = "package"
const val KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS = "exportForwardDeclarations"
const val KLIB_PROPERTY_INCLUDED_HEADERS = "includedHeaders"
val libDir: File
val target: KonanTarget?
// This is a default implementation. Can't make it an assignment.
get() = null
interface KonanLibrary {
val manifestFile
get() = File(libDir, "manifest")
val resourcesDir
get() = File(libDir, "resources")
val targetsDir
get() = File(libDir, "targets")
val targetDir
get() = File(targetsDir, target!!.visibleName)
val kotlinDir
get() = File(targetDir, "kotlin")
val nativeDir
get() = File(targetDir, "native")
val includedDir
get() = File(targetDir, "included")
val linkdataDir
get() = File(libDir, "linkdata")
val moduleHeaderFile
get() = File(linkdataDir, "module")
val dataFlowGraphFile
get() = File(linkdataDir, "module_data_flow_graph")
fun packageFile(packageName: String)
= File(linkdataDir, if (packageName == "") "root_package.knm" else "package_$packageName.knm")
}
interface KonanLibrary: KonanLibraryLayout {
val libraryName: String
val libraryFile: File
// properties:
val manifestProperties: Properties
val abiVersion: String
val linkerOpts: List<String>
// paths:
val bitcodePaths: List<String>
val includedPaths: List<String>
val targetList: List<String>
val dataFlowGraph: ByteArray?
val moduleHeaderData: ByteArray
fun packageMetadata(fqName: String): ByteArray
// FIXME: ddol: to be refactored into some global resolution context
val isDefaultLibrary: Boolean get() = false
val isNeededForLink: Boolean get() = true
val resolvedDependencies: MutableList<KonanLibrary>
fun markPackageAccessed(fqName: String)
}
val KonanLibrary.uniqueName
get() = manifestProperties.getProperty(KLIB_PROPERTY_UNIQUE_NAME)!!
val KonanLibrary.unresolvedDependencies: List<String>
get() = manifestProperties.propertyList(KLIB_PROPERTY_DEPENDS)
val KonanLibrary.isInterop
get() = manifestProperties.getProperty(KLIB_PROPERTY_INTEROP) == "true"
val KonanLibrary.packageFqName
get() = manifestProperties.getProperty(KLIB_PROPERTY_PACKAGE)?.let { FqName(it) }
val KonanLibrary.exportForwardDeclarations
get() = manifestProperties.getProperty(KLIB_PROPERTY_EXPORT_FORWARD_DECLARATIONS)
.split(' ')
.map { it.trim() }
.filter { it.isNotEmpty() }
.map { FqName(it) }
val KonanLibrary.includedHeaders
get() = manifestProperties.getProperty(KLIB_PROPERTY_INCLUDED_HEADERS).split(' ')
@@ -0,0 +1,45 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.KonanTarget
const val KLIB_FILE_EXTENSION = "klib"
const val KLIB_FILE_EXTENSION_WITH_DOT = ".$KLIB_FILE_EXTENSION"
// This scheme describes the Kotlin/Native Library (klib) layout.
interface KonanLibraryLayout {
val libraryName: String
val libDir: File
val target: KonanTarget?
// This is a default implementation. Can't make it an assignment.
get() = null
val manifestFile
get() = File(libDir, "manifest")
val resourcesDir
get() = File(libDir, "resources")
val targetsDir
get() = File(libDir, "targets")
val targetDir
get() = File(targetsDir, target!!.visibleName)
val kotlinDir
get() = File(targetDir, "kotlin")
val nativeDir
get() = File(targetDir, "native")
val includedDir
get() = File(targetDir, "included")
val linkdataDir
get() = File(libDir, "linkdata")
val moduleHeaderFile
get() = File(linkdataDir, "module")
val dataFlowGraphFile
get() = File(linkdataDir, "module_data_flow_graph")
fun packageFile(packageName: String)
= File(linkdataDir, if (packageName == "") "root_package.knm" else "package_$packageName.knm")
}
@@ -1,28 +0,0 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.properties.Properties
interface KonanLibraryReader {
val libraryFile: File
val libraryName: String
val manifestProperties: Properties
val uniqueName: String
val linkerOpts: List<String>
val unresolvedDependencies: List<String>
val bitcodePaths: List<String>
val includedPaths: List<String>
val dataFlowGraph: ByteArray?
val moduleHeaderData: ByteArray
fun packageMetadata(fqName: String): ByteArray
val isDefaultLibrary: Boolean get() = false
// FIXME: ddol: to be refactored into some global resolution context
val isNeededForLink: Boolean get() = true
val resolvedDependencies: MutableList<KonanLibraryReader>
fun markPackageAccessed(fqName: String)
}
@@ -0,0 +1,32 @@
package org.jetbrains.kotlin.konan.library
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.impl.DefaultMetadataReaderImpl
import org.jetbrains.kotlin.konan.library.impl.KonanLibraryImpl
import org.jetbrains.kotlin.konan.library.impl.zippedKonanLibraryChecks
import org.jetbrains.kotlin.konan.library.impl.zippedKonanLibraryRoot
import org.jetbrains.kotlin.konan.target.KonanTarget
fun File.unpackZippedKonanLibraryTo(newDir: File) {
// first run validity checks for the given KLIB file
zippedKonanLibraryChecks(this)
if (newDir.exists) {
if (newDir.isDirectory)
newDir.deleteRecursively()
else
newDir.delete()
}
zippedKonanLibraryRoot(this).recursiveCopyTo(newDir)
check(newDir.exists) { "Could not unpack $this as $newDir." }
}
fun createKonanLibraryReader(
libraryFile: File,
currentAbiVersion: Int,
target: KonanTarget? = null,
isDefaultLibrary: Boolean = false,
metadataReader: MetadataReader = DefaultMetadataReaderImpl
): KonanLibrary = KonanLibraryImpl(libraryFile, currentAbiVersion, target, isDefaultLibrary, metadataReader)
@@ -1,6 +1,6 @@
package org.jetbrains.kotlin.konan.library
interface MetadataReader {
fun loadSerializedModule(library: KonanLibrary): ByteArray
fun loadSerializedPackageFragment(library: KonanLibrary, fqName: String): ByteArray
fun loadSerializedModule(libraryLayout: KonanLibraryLayout): ByteArray
fun loadSerializedPackageFragment(libraryLayout: KonanLibraryLayout, fqName: String): ByteArray
}
@@ -1,12 +1,13 @@
package org.jetbrains.kotlin.konan.library.impl
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
import org.jetbrains.kotlin.konan.library.MetadataReader
object DefaultMetadataReaderImpl : MetadataReader {
internal object DefaultMetadataReaderImpl : MetadataReader {
override fun loadSerializedModule(library: KonanLibrary): ByteArray = library.moduleHeaderFile.readBytes()
override fun loadSerializedModule(libraryLayout: KonanLibraryLayout): ByteArray =
libraryLayout.moduleHeaderFile.readBytes()
override fun loadSerializedPackageFragment(library: KonanLibrary, fqName: String): ByteArray =
library.packageFile(fqName).readBytes()
override fun loadSerializedPackageFragment(libraryLayout: KonanLibraryLayout, fqName: String): ByteArray =
libraryLayout.packageFile(fqName).readBytes()
}
@@ -1,85 +1,79 @@
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.util.removeSuffixIfPresent
import org.jetbrains.kotlin.konan.file.*
import org.jetbrains.kotlin.konan.library.MetadataReader
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions
import org.jetbrains.kotlin.konan.util.substitute
import org.jetbrains.kotlin.serialization.konan.emptyPackages
const val KLIB_FILE_EXTENSION = "klib"
const val KLIB_FILE_EXTENSION_WITH_DOT = ".$KLIB_FILE_EXTENSION"
internal class KonanLibraryImpl(
override val libraryFile: File,
private val currentAbiVersion: Int,
internal val target: KonanTarget?,
override val isDefaultLibrary: Boolean,
private val metadataReader: MetadataReader
) : KonanLibrary {
class ZippedKonanLibrary(val klibFile: File, override val target: KonanTarget? = null): KonanLibrary {
init {
check(klibFile.exists) { "Could not find $klibFile." }
check(klibFile.isFile) { "Expected $klibFile to be a regular file." }
// For the zipped libraries inPlace gives files from zip file system
// whereas realFiles extracts them to /tmp.
// For unzipped libraries inPlace and realFiles are the same
// providing files in the library directory.
private val inPlace = createKonanLibraryLayout(libraryFile, target)
private val realFiles = inPlace.realFiles
val extension = klibFile.extension
check(extension.isEmpty() || extension == KLIB_FILE_EXTENSION) { "Unexpected file extension: $extension" }
override val libraryName
get() = inPlace.libraryName
override val manifestProperties: Properties by lazy {
val properties = inPlace.manifestFile.loadProperties()
if (target != null) substitute(properties, defaultTargetSubstitutions(target))
properties
}
override val libraryName = klibFile.path.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT)
override val libDir by lazy { klibFile.asZipRoot }
fun unpackTo(newDir: File) {
if (newDir.exists) {
if (newDir.isDirectory)
newDir.deleteRecursively()
else
newDir.delete()
override val abiVersion: String
get() {
val manifestAbiVersion = manifestProperties.getProperty(KLIB_PROPERTY_ABI_VERSION)
check(currentAbiVersion.toString() == manifestAbiVersion) {
"ABI version mismatch. Compiler expects: $currentAbiVersion, the library is $manifestAbiVersion"
}
return manifestAbiVersion
}
override val linkerOpts: List<String>
get() = manifestProperties.propertyList(KLIB_PROPERTY_LINKED_OPTS, target!!.visibleName)
override val bitcodePaths: List<String>
get() = (realFiles.kotlinDir.listFilesOrEmpty + realFiles.nativeDir.listFilesOrEmpty).map { it.absolutePath }
override val includedPaths: List<String>
get() = realFiles.includedDir.listFilesOrEmpty.map { it.absolutePath }
override val targetList by lazy { inPlace.targetsDir.listFiles.map { it.name } }
override val dataFlowGraph by lazy { inPlace.dataFlowGraphFile.let { if (it.exists) it.readBytes() else null } }
override val moduleHeaderData: ByteArray by lazy { metadataReader.loadSerializedModule(inPlace) }
override fun packageMetadata(fqName: String) = metadataReader.loadSerializedPackageFragment(inPlace, fqName)
override var isNeededForLink: Boolean = false
private set
override val resolvedDependencies = mutableListOf<KonanLibrary>()
override fun markPackageAccessed(fqName: String) {
if (!isNeededForLink // fast path
&& !emptyPackages.contains(fqName)) {
isNeededForLink = true
}
libDir.recursiveCopyTo(newDir)
check(newDir.exists) { "Could not unpack $klibFile as $newDir." }
}
private val emptyPackages by lazy { emptyPackages(moduleHeaderData) }
}
// This class automatically extracts pieces of
// the library on first access. Use it if you need
// to pass extracted files to an external tool.
// Otherwise, stick to ZippedKonanLibrary.
private class FileExtractor(zippedLibrary: KonanLibrary): KonanLibrary by zippedLibrary {
override val manifestFile: File by lazy { extract(super.manifestFile) }
override val resourcesDir: File by lazy { extractDir(super.resourcesDir) }
override val includedDir: File by lazy { extractDir(super.includedDir) }
override val kotlinDir: File by lazy { extractDir(super.kotlinDir) }
override val nativeDir: File by lazy { extractDir(super.nativeDir) }
override val linkdataDir: File by lazy { extractDir(super.linkdataDir) }
fun extract(file: File): File {
val temporary = createTempFile(file.name)
file.copyTo(temporary)
temporary.deleteOnExit()
return temporary
}
fun extractDir(directory: File): File {
val temporary = createTempDir(directory.name)
directory.recursiveCopyTo(temporary)
temporary.deleteOnExitRecursively()
return temporary
}
}
class UnzippedKonanLibrary(override val libDir: File, override val target: KonanTarget? = null): KonanLibrary {
override val libraryName = libDir.path
val targetList: List<String> by lazy { targetsDir.listFiles.map { it.name } }
}
fun KonanLibrary(klib: File, target: KonanTarget? = null) =
if (klib.isFile) ZippedKonanLibrary(klib, target) else UnzippedKonanLibrary(klib, target)
internal val KonanLibrary.realFiles
get() = when (this) {
is ZippedKonanLibrary -> FileExtractor(this)
// Unpacked library just provides its own files.
is UnzippedKonanLibrary -> this
else -> error("Provide an extractor for your container.")
}
@@ -0,0 +1,79 @@
package org.jetbrains.kotlin.konan.library.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.file.asZipRoot
import org.jetbrains.kotlin.konan.file.createTempDir
import org.jetbrains.kotlin.konan.file.createTempFile
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION
import org.jetbrains.kotlin.konan.library.KLIB_FILE_EXTENSION_WITH_DOT
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
private class ZippedKonanLibraryLayout(val klibFile: File, override val target: KonanTarget? = null): KonanLibraryLayout {
init { zippedKonanLibraryChecks(klibFile) }
override val libraryName = klibFile.path.removeSuffixIfPresent(KLIB_FILE_EXTENSION_WITH_DOT)
override val libDir by lazy { zippedKonanLibraryRoot(klibFile) }
}
internal fun zippedKonanLibraryChecks(klibFile: File) {
check(klibFile.exists) { "Could not find $klibFile." }
check(klibFile.isFile) { "Expected $klibFile to be a regular file." }
val extension = klibFile.extension
check(extension.isEmpty() || extension == KLIB_FILE_EXTENSION) { "Unexpected file extension: $extension" }
}
internal fun zippedKonanLibraryRoot(klibFile: File) = klibFile.asZipRoot
private class UnzippedKonanLibraryLayout(override val libDir: File, override val target: KonanTarget? = null): KonanLibraryLayout {
override val libraryName = libDir.path
}
// This class automatically extracts pieces of
// the library on first access. Use it if you need
// to pass extracted files to an external tool.
// Otherwise, stick to ZippedKonanLibrary.
private class FileExtractor(zippedLibraryLayout: KonanLibraryLayout): KonanLibraryLayout by zippedLibraryLayout {
override val manifestFile: File by lazy { extract(super.manifestFile) }
override val resourcesDir: File by lazy { extractDir(super.resourcesDir) }
override val includedDir: File by lazy { extractDir(super.includedDir) }
override val kotlinDir: File by lazy { extractDir(super.kotlinDir) }
override val nativeDir: File by lazy { extractDir(super.nativeDir) }
override val linkdataDir: File by lazy { extractDir(super.linkdataDir) }
fun extract(file: File): File {
val temporary = createTempFile(file.name)
file.copyTo(temporary)
temporary.deleteOnExit()
return temporary
}
fun extractDir(directory: File): File {
val temporary = createTempDir(directory.name)
directory.recursiveCopyTo(temporary)
temporary.deleteOnExitRecursively()
return temporary
}
}
internal fun createKonanLibraryLayout(klib: File, target: KonanTarget? = null) =
if (klib.isFile) ZippedKonanLibraryLayout(klib, target) else UnzippedKonanLibraryLayout(klib, target)
internal val KonanLibraryLayout.realFiles
get() = when (this) {
is ZippedKonanLibraryLayout -> FileExtractor(this)
// Unpacked library just provides its own files.
is UnzippedKonanLibraryLayout -> this
else -> error("Provide an extractor for your container.")
}
@@ -1,83 +0,0 @@
package org.jetbrains.kotlin.konan.library.impl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.konan.library.MetadataReader
import org.jetbrains.kotlin.konan.properties.Properties
import org.jetbrains.kotlin.konan.properties.loadProperties
import org.jetbrains.kotlin.konan.properties.propertyList
import org.jetbrains.kotlin.konan.properties.propertyString
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions
import org.jetbrains.kotlin.konan.util.substitute
import org.jetbrains.kotlin.serialization.konan.emptyPackages
class LibraryReaderImpl(
override val libraryFile: File,
val currentAbiVersion: Int,
val target: KonanTarget? = null,
override val isDefaultLibrary: Boolean = false,
private val metadataReader: MetadataReader = DefaultMetadataReaderImpl
) : KonanLibraryReader {
// For the zipped libraries inPlace gives files from zip file system
// whereas realFiles extracts them to /tmp.
// For unzipped libraries inPlace and realFiles are the same
// providing files in the library directory.
private val inPlace = KonanLibrary(libraryFile, target)
private val realFiles = inPlace.realFiles
override val manifestProperties: Properties by lazy {
val properties = inPlace.manifestFile.loadProperties()
if (target != null) substitute(properties, defaultTargetSubstitutions(target))
properties
}
val abiVersion: String
get() {
val manifestAbiVersion = manifestProperties.getProperty("abi_version")
check("$currentAbiVersion" == manifestAbiVersion) {
"ABI version mismatch. Compiler expects: $currentAbiVersion, the library is $manifestAbiVersion"
}
return manifestAbiVersion
}
val targetList = inPlace.targetsDir.listFiles.map { it.name }
override val dataFlowGraph by lazy { inPlace.dataFlowGraphFile.let { if (it.exists) it.readBytes() else null } }
override val libraryName
get() = inPlace.libraryName
override val uniqueName
get() = manifestProperties.propertyString("unique_name")!!
override val bitcodePaths: List<String>
get() = (realFiles.kotlinDir.listFilesOrEmpty + realFiles.nativeDir.listFilesOrEmpty).map { it.absolutePath }
override val includedPaths: List<String>
get() = realFiles.includedDir.listFilesOrEmpty.map { it.absolutePath }
override val linkerOpts: List<String>
get() = manifestProperties.propertyList("linkerOpts", target!!.visibleName)
override val unresolvedDependencies: List<String>
get() = manifestProperties.propertyList("depends")
override val resolvedDependencies = mutableListOf<KonanLibraryReader>()
override val moduleHeaderData: ByteArray by lazy { metadataReader.loadSerializedModule(inPlace) }
override var isNeededForLink: Boolean = false
private set
private val emptyPackages by lazy { emptyPackages(moduleHeaderData) }
override fun markPackageAccessed(fqName: String) {
if (!isNeededForLink // fast path
&& !emptyPackages.contains(fqName)) {
isNeededForLink = true
}
}
override fun packageMetadata(fqName: String) = metadataReader.loadSerializedPackageFragment(inPlace, fqName)
}
@@ -7,8 +7,10 @@ import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.createKonanModuleDescriptor
import org.jetbrains.kotlin.descriptors.konan.interop.InteropFqNames
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.exportForwardDeclarations
import org.jetbrains.kotlin.konan.library.isInterop
import org.jetbrains.kotlin.konan.library.packageFqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.serialization.deserialization.*
@@ -19,7 +21,7 @@ import org.jetbrains.kotlin.storage.StorageManager
interface KonanModuleDescriptorFactory {
fun createModuleDescriptor(
libraryReader: KonanLibraryReader,
libraryReader: KonanLibrary,
specifics: LanguageVersionSettings,
storageManager: StorageManager = LockBasedStorageManager()
): ModuleDescriptor
@@ -28,7 +30,7 @@ interface KonanModuleDescriptorFactory {
object DefaultKonanModuleDescriptorFactory: KonanModuleDescriptorFactory {
override fun createModuleDescriptor(
libraryReader: KonanLibraryReader,
libraryReader: KonanLibrary,
specifics: LanguageVersionSettings,
storageManager: StorageManager
): ModuleDescriptorImpl {
@@ -57,7 +59,7 @@ object DefaultKonanModuleDescriptorFactory: KonanModuleDescriptorFactory {
}
private fun createPackageFragmentProvider(
libraryReader: KonanLibraryReader,
libraryReader: KonanLibrary,
fragmentNames: List<String>,
storageManager: StorageManager,
moduleDescriptor: ModuleDescriptor,
@@ -106,21 +108,17 @@ object DefaultKonanModuleDescriptorFactory: KonanModuleDescriptorFactory {
}
private fun getSyntheticPackageFragments(
libraryReader: KonanLibraryReader,
libraryReader: KonanLibrary,
moduleDescriptor: ModuleDescriptor,
konanPackageFragments: List<KonanPackageFragment>
): List<PackageFragmentDescriptor> {
if (libraryReader.manifestProperties.getProperty("interop") != "true") return emptyList()
if (!libraryReader.isInterop) return emptyList()
val packageFqName = libraryReader.manifestProperties.getProperty("package")?.let { FqName(it) }
val packageFqName = libraryReader.packageFqName
?: error("Inconsistent manifest: interop library ${libraryReader.libraryName} should have `package` specified")
val exportForwardDeclarations = libraryReader.manifestProperties.getProperty("exportForwardDeclarations")
.split(' ')
.map { it.trim() }
.filter { it.isNotEmpty() }
.map { FqName(it) }
val exportForwardDeclarations = libraryReader.exportForwardDeclarations
val interopPackageFragments = konanPackageFragments.filter { it.fqName == packageFqName }
@@ -1,7 +1,7 @@
package org.jetbrains.kotlin.serialization.konan
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
@@ -15,7 +15,7 @@ import org.jetbrains.kotlin.storage.StorageManager
class KonanPackageFragment(
val fqNameString: String,
val reader: KonanLibraryReader,
val reader: KonanLibrary,
storageManager: StorageManager,
module: ModuleDescriptor
) : DeserializedPackageFragment(FqName(fqNameString), storageManager, module) {