move Kotlin/Native metadata deserialization and KLIB reader to a separate module (#1908)

1. move Kotlin/Native metadata deserialization and KLIB reader to a separate module
2. decouple KLIB reader from ModuleDescriptor creation
This commit is contained in:
Dmitriy Dolovov
2018-08-22 14:01:20 +03:00
committed by GitHub
parent 0f00b39fda
commit f0cfbb9918
47 changed files with 610 additions and 720 deletions
+2 -1
View File
@@ -140,11 +140,12 @@ dependencies {
compilerCompile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion"
compilerCompile "org.jetbrains.kotlin:konan.descriptors:$konanVersion"
compilerCompile "org.jetbrains.kotlin:konan.metadata:$konanVersion"
compilerCompile "org.jetbrains.kotlin:konan.metadata.serializer:$konanVersion"
compilerCompile "org.jetbrains.kotlin:konan.serializer:$konanVersion"
cli_bcCompile kotlinCompilerModule
cli_bcCompile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion"
cli_bcCompile sourceSets.compiler.output
cli_bcCompile "org.jetbrains.kotlin:konan.serializer:$konanVersion"
bc_frontendCompile kotlinCompilerModule
@@ -20,7 +20,6 @@ import com.intellij.openapi.Disposable
import org.jetbrains.annotations.NotNull
import org.jetbrains.annotations.Nullable
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.serialization.KonanMetadataVersion
import org.jetbrains.kotlin.cli.common.CLICompiler
import org.jetbrains.kotlin.cli.common.CLITool
import org.jetbrains.kotlin.cli.common.CommonCompilerPerformanceManager
@@ -32,7 +31,9 @@ import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity.WARNING
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser
import org.jetbrains.kotlin.config.*
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.config.Services
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
@@ -40,6 +41,7 @@ import org.jetbrains.kotlin.konan.util.profile
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.utils.KotlinPaths
import org.jetbrains.kotlin.serialization.konan.KonanMetadataVersion
private class K2NativeCompilerPerformanceManager: CommonCompilerPerformanceManager("Kotlin to Native Compiler")
class K2Native : CLICompiler<K2NativeCompilerArguments>() {
@@ -16,14 +16,8 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.descriptors.ClassifierAliasingPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.konan.descriptors.ExportedForwardDeclarationsPackageFragmentDescriptor
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.serialization.KonanPackageFragment
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.konan.interop.InteropFqNames
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.name.FqName
@@ -32,25 +26,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.util.OperatorNameConventions
interface InteropLibrary {
fun createSyntheticPackages(
module: ModuleDescriptor,
konanPackageFragments: List<KonanPackageFragment>
): List<PackageFragmentDescriptor>
}
fun createInteropLibrary(reader: KonanLibraryReader): InteropLibrary? {
if (reader.manifestProperties.getProperty("interop") != "true") return null
val pkg = reader.manifestProperties.getProperty("package")
?: error("Inconsistent manifest: interop library ${reader.libraryName} should have `package` specified")
val exportForwardDeclarations = reader.manifestProperties
.getProperty("exportForwardDeclarations").split(' ')
.map { it.trim() }.filter { it.isNotEmpty() }
.map { FqName(it) }
return InteropLibraryImpl(FqName(pkg), exportForwardDeclarations)
}
internal class InteropBuiltIns(builtIns: KonanBuiltIns, vararg konanPrimitives: ClassDescriptor) {
val packageScope = builtIns.builtInsModule.getPackage(InteropFqNames.packageName).memberScope
@@ -183,29 +158,3 @@ private fun MemberScope.getContributedClass(name: String): ClassDescriptor =
private fun MemberScope.getContributedFunctions(name: String) =
this.getContributedFunctions(Name.identifier(name), NoLookupLocation.FROM_BUILTINS)
private class InteropLibraryImpl(
private val packageFqName: FqName,
private val exportForwardDeclarations: List<FqName>
) : InteropLibrary {
override fun createSyntheticPackages(
module: ModuleDescriptor,
konanPackageFragments: List<KonanPackageFragment>
): List<PackageFragmentDescriptor> {
val interopPackageFragments = konanPackageFragments.filter { it.fqName == packageFqName }
val result = mutableListOf<PackageFragmentDescriptor>()
// Allow references to forwarding declarations to be resolved into classifiers declared in this library:
listOf(InteropFqNames.cNamesStructs, InteropFqNames.objCNamesClasses, InteropFqNames.objCNamesProtocols).mapTo(result) { fqName ->
ClassifierAliasingPackageFragmentDescriptor(interopPackageFragments, module, fqName)
}
// TODO: use separate namespaces for structs, enums, Objective-C protocols etc.
result.add(ExportedForwardDeclarationsPackageFragmentDescriptor(
module, packageFqName, exportForwardDeclarations
))
return result
}
}
@@ -17,9 +17,6 @@
package org.jetbrains.kotlin.backend.konan
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl
import org.jetbrains.kotlin.backend.konan.library.impl.purgeUnneeded
import org.jetbrains.kotlin.backend.konan.library.resolveImmediateLibraries
import org.jetbrains.kotlin.backend.konan.library.resolveLibrariesRecursive
import org.jetbrains.kotlin.backend.konan.library.withResolvedDependencies
@@ -35,9 +32,11 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.konan.interop.createForwardDeclarationsModule
import org.jetbrains.kotlin.konan.TempFiles
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.konan.library.defaultResolver
import org.jetbrains.kotlin.konan.target.*
import org.jetbrains.kotlin.konan.util.profile
import org.jetbrains.kotlin.serialization.konan.DefaultKonanModuleDescriptorFactory
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
@@ -94,7 +93,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
private val repositories = configuration.getList(KonanConfigKeys.REPOSITORIES)
private val resolver = defaultResolver(repositories, target, distribution)
internal val immediateLibraries: List<LibraryReaderImpl> by lazy {
internal val immediateLibraries: List<KonanLibraryReader> by lazy {
val result = resolver.resolveImmediateLibraries(libraryNames, target,
currentAbiVersion,
configuration.getBoolean(KonanConfigKeys.NOSTDLIB),
@@ -136,7 +135,7 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
for (klib in libraries) {
profile("Loading ${klib.libraryName}") {
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
val moduleDescriptor = klib.moduleDescriptor(specifics)
val moduleDescriptor = DefaultKonanModuleDescriptorFactory.createModuleDescriptor(klib, specifics)
allMetadata.add(moduleDescriptor)
friendLibsSet?.apply {
if (contains(klib.libraryFile))
@@ -175,3 +174,6 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
fun CompilerConfiguration.report(priority: CompilerMessageSeverity, message: String)
= this.getNotNull(CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY).report(priority, message)
private fun <T: KonanLibraryReader> List<T>.purgeUnneeded(config: KonanConfig): List<T> =
this.filter{ (!it.isDefaultLibrary && !config.purgeUserLibs) || it.isNeededForLink }
@@ -1,95 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.descriptors
import org.jetbrains.kotlin.backend.konan.serialization.KonanPackageFragment
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
/**
* The package fragment to export forward declarations from interop package namespace, i.e.
* redirect "$pkg.$name" to e.g. "cnames.structs.$name".
*/
class ExportedForwardDeclarationsPackageFragmentDescriptor(
module: ModuleDescriptor, fqName: FqName, declarations: List<FqName>
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
private val nameToFqName = declarations.map { it.shortName() to it }.toMap()
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? {
val declFqName = nameToFqName[name] ?: return null
val packageView = module.getPackage(declFqName.parent())
return packageView.memberScope.getContributedClassifier(name, location)
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
// TODO
p.popIndent()
p.println("}")
}
}
override fun getMemberScope() = memberScope
}
/**
* The package fragment that redirects all requests for classifier lookup to its targets.
*/
class ClassifierAliasingPackageFragmentDescriptor(
targets: List<KonanPackageFragment>, module: ModuleDescriptor, fqName: FqName
) : PackageFragmentDescriptorImpl(module, fqName) {
private val memberScope = object : MemberScopeImpl() {
override fun getContributedClassifier(name: Name, location: LookupLocation) =
targets.firstNotNullResult {
if (it.hasTopLevelClassifier(name)) {
it.getMemberScope().getContributedClassifier(name, location)
} else {
null
}
}
override fun printScopeStructure(p: Printer) {
p.println(this::class.java.simpleName, " {")
p.pushIndent()
p.println("targets = " + targets)
p.popIndent()
p.println("}")
}
}
override fun getMemberScope(): MemberScope = memberScope
}
@@ -1,56 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.library
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.util.visibleName
// This scheme describes the Konan Library (klib) layout.
interface KonanLibraryLayout {
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")
}
interface KonanLibrary: KonanLibraryLayout {
val libraryName: String
}
@@ -1,43 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.library
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.konan.properties.Properties
interface KonanLibraryReader {
val libraryName: String
val uniqueName: String
val bitcodePaths: List<String>
val includedPaths: List<String>
val linkerOpts: List<String>
val unresolvedDependencies: List<String>
val dataFlowGraph: ByteArray?
val isDefaultLibrary: Boolean get() = false
val isNeededForLink: Boolean get() = true
val manifestProperties: Properties
val moduleHeaderData: ByteArray
fun packageMetadata(fqName: String): ByteArray
fun markPackageAccessed(fqName: String)
fun moduleDescriptor(specifics: LanguageVersionSettings): ModuleDescriptor
}
interface MetadataReader {
fun loadSerializedModule(): ByteArray
fun loadSerializedPackageFragment(fqName: String): ByteArray
}
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.backend.konan.library
import llvm.LLVMModuleRef
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
interface KonanLibraryWriter {
fun addLinkData(linkData: LinkData)
@@ -16,22 +16,29 @@
package org.jetbrains.kotlin.backend.konan.library
import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.konan.library.SearchPathResolver
import org.jetbrains.kotlin.konan.library.impl.LibraryReaderImpl
import org.jetbrains.kotlin.konan.target.KonanTarget
const val KONAN_CURRENT_ABI_VERSION = 1
/**
* Returns the list of [KonanLibraryReader]s given the list of user provided [libraryNames] along with
* other parameters: [target], [abiVersion], [noStdLib], [noDefaultLibs].
*/
fun SearchPathResolver.resolveImmediateLibraries(libraryNames: List<String>,
target: KonanTarget,
abiVersion: Int = 1,
abiVersion: Int = KONAN_CURRENT_ABI_VERSION,
noStdLib: Boolean = false,
noDefaultLibs: Boolean = false,
logger: ((String) -> Unit)?): List<LibraryReaderImpl> {
logger: ((String) -> Unit)?): List<KonanLibraryReader> {
val userProvidedLibraries = libraryNames
.map { resolve(it) }
.map{ LibraryReaderImpl(it, abiVersion, target) }
val defaultLibraries = defaultLinks(nostdlib = noStdLib, noDefaultLibs = noDefaultLibs).map {
val defaultLibraries = defaultLinks(noStdLib = noStdLib, noDefaultLibs = noDefaultLibs).map {
LibraryReaderImpl(it, abiVersion, target, isDefaultLibrary = true)
}
@@ -44,8 +51,7 @@ fun SearchPathResolver.resolveImmediateLibraries(libraryNames: List<String>,
return resolvedLibraries.distinctBy { it.libraryFile.absolutePath }
}
private fun warnOnLibraryDuplicates(resolvedLibraries: List<File>,
logger: ((String) -> Unit)? ) {
private fun warnOnLibraryDuplicates(resolvedLibraries: List<File>, logger: ((String) -> Unit)? ) {
if (logger == null) return
@@ -56,38 +62,46 @@ private fun warnOnLibraryDuplicates(resolvedLibraries: List<File>,
}
}
fun SearchPathResolver.resolveLibrariesRecursive(immediateLibraries: List<LibraryReaderImpl>,
/**
* For each of the given [immediateLibraries] fills in `resolvedDependencies` field with the
* [KonanLibraryReader]s the library !!directly!! depends on.
*/
fun SearchPathResolver.resolveLibrariesRecursive(immediateLibraries: List<KonanLibraryReader>,
target: KonanTarget,
abiVersion: Int) {
val cache = mutableMapOf<File, LibraryReaderImpl>()
val cache = mutableMapOf<File, KonanLibraryReader>()
cache.putAll(immediateLibraries.map { it.libraryFile.absoluteFile to it })
var newDependencies = cache.values.toList()
do {
newDependencies = newDependencies.map { library: LibraryReaderImpl ->
newDependencies = newDependencies.map { library: KonanLibraryReader ->
library.unresolvedDependencies
.map { resolve(it).absoluteFile }
.map {
.mapNotNull {
if (it in cache) {
library.resolvedDependencies.add(cache[it]!!)
null
} else {
val reader = LibraryReaderImpl(it, abiVersion, target)
cache.put(it,reader)
library.resolvedDependencies.add(reader)
cache[it] = reader
library.resolvedDependencies.add(reader)
reader
}
}.filterNotNull()
}
} .flatten()
} while (newDependencies.isNotEmpty())
}
fun List<LibraryReaderImpl>.withResolvedDependencies(): List<LibraryReaderImpl> {
val result = mutableSetOf<LibraryReaderImpl>()
/**
* For the given list of [KonanLibraryReader]s returns the list of [KonanLibraryReader]s
* that includes the same libraries plus all their (transitive) dependencies.
*/
fun List<KonanLibraryReader>.withResolvedDependencies(): List<KonanLibraryReader> {
val result = mutableSetOf<KonanLibraryReader>()
result.addAll(this)
var newDependencies = result.toList()
do {
newDependencies = newDependencies
.map { it -> it.resolvedDependencies } .flatten()
.map { it -> it.resolvedDependencies }.flatten()
.filter { it !in result }
result.addAll(newDependencies)
} while (newDependencies.isNotEmpty())
@@ -96,9 +110,9 @@ fun List<LibraryReaderImpl>.withResolvedDependencies(): List<LibraryReaderImpl>
fun SearchPathResolver.resolveLibrariesRecursive(libraryNames: List<String>,
target: KonanTarget,
abiVersion: Int = 1,
abiVersion: Int = KONAN_CURRENT_ABI_VERSION,
noStdLib: Boolean = false,
noDefaultLibs: Boolean = false): List<LibraryReaderImpl> {
noDefaultLibs: Boolean = false): List<KonanLibraryReader> {
val immediateLibraries = resolveImmediateLibraries(
libraryNames = libraryNames,
target = target,
@@ -1,116 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.library.impl
import org.jetbrains.kotlin.backend.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.util.removeSuffixIfPresent
import org.jetbrains.kotlin.konan.file.*
import org.jetbrains.kotlin.konan.target.KonanTarget
open class ZippedKonanLibrary(val klibFile: File, override val target: KonanTarget? = null): KonanLibrary {
init {
if (!klibFile.exists) {
error("Could not find $klibFile.")
}
if (!klibFile.isFile) {
error("Expected $klibFile to be a regular file.")
}
}
override val libraryName = klibFile.path.removeSuffixIfPresent(".klib")
override val libDir by lazy {
klibFile.asZipRoot
}
fun unpackTo(newDir: File) {
if (newDir.exists) {
if (newDir.isDirectory)
newDir.deleteRecursively()
else
newDir.delete()
}
libDir.recursiveCopyTo(newDir)
if (!newDir.exists) error("Could not unpack $klibFile as $newDir.")
}
}
// 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.
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)
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.")
}
@@ -1,108 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.library.impl
import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.serialization.emptyPackages
import org.jetbrains.kotlin.backend.konan.serialization.deserializeModule
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.properties.*
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.konan.util.defaultTargetSubstitutions
import org.jetbrains.kotlin.konan.util.substitute
class LibraryReaderImpl(var libraryFile: File, val currentAbiVersion: Int,
val target: KonanTarget? = null, override val isDefaultLibrary: Boolean = false)
: 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
private val reader = MetadataReaderImpl(inPlace)
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")
if ("$currentAbiVersion" != manifestAbiVersion)
error("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")
val resolvedDependencies = mutableListOf<LibraryReaderImpl>()
override val moduleHeaderData: ByteArray by lazy {
reader.loadSerializedModule()
}
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): ByteArray {
return reader.loadSerializedPackageFragment(fqName)
}
override fun moduleDescriptor(specifics: LanguageVersionSettings)
= deserializeModule(specifics, this)
}
internal fun <T: KonanLibraryReader> List<T>.purgeUnneeded(config: KonanConfig): List<T> =
this.filter{ (!it.isDefaultLibrary && !config.purgeUserLibs) || it.isNeededForLink }
@@ -16,10 +16,10 @@
package org.jetbrains.kotlin.backend.konan.library.impl
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import llvm.LLVMModuleRef
import llvm.LLVMWriteBitcodeToFile
import org.jetbrains.kotlin.backend.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter
import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.konan.file.*
@@ -1,30 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.library.impl
import org.jetbrains.kotlin.backend.konan.library.KonanLibrary
import org.jetbrains.kotlin.backend.konan.library.MetadataReader
class MetadataReaderImpl(library: KonanLibrary) : MetadataReader, KonanLibrary by library {
override fun loadSerializedModule(): ByteArray {
return moduleHeaderFile.readBytes()
}
override fun loadSerializedPackageFragment(fqName: String)
= packageFile(fqName).readBytes()
}
@@ -16,9 +16,8 @@
package org.jetbrains.kotlin.backend.konan.library.impl
import org.jetbrains.kotlin.backend.konan.library.KonanLibrary
import org.jetbrains.kotlin.konan.library.KonanLibrary
import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.konan.file.File
internal class MetadataWriterImpl(library: KonanLibrary): KonanLibrary by library {
@@ -20,7 +20,7 @@ import llvm.LLVMTypeRef
import org.jetbrains.kotlin.backend.konan.descriptors.isAbstract
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.isInlined
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.optimizations.DataFlowIR
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PropertyAccessorDescriptor
@@ -25,8 +25,7 @@ import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.findPackage
import org.jetbrains.kotlin.backend.konan.hash.GlobalHash
import org.jetbrains.kotlin.backend.konan.irasdescriptors.*
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.impl.LibraryReaderImpl
import org.jetbrains.kotlin.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.withResolvedDependencies
import org.jetbrains.kotlin.descriptors.konan.CompiledKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.CurrentKonanModuleOrigin
@@ -324,7 +323,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
return function
}
private val usedLibraries = mutableSetOf<LibraryReaderImpl>()
private val usedLibraries = mutableSetOf<KonanLibraryReader>()
val imports = object : LlvmImports {
@@ -340,7 +339,7 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
error("$reader (${reader.libraryName}) is used but not requested")
}
usedLibraries.add(reader as LibraryReaderImpl)
usedLibraries.add(reader)
}
}
@@ -351,12 +350,12 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
.topoSort()
}
private fun List<LibraryReaderImpl>.topoSort(): List<LibraryReaderImpl> {
var sorted = mutableListOf<LibraryReaderImpl>()
val visited = mutableSetOf<LibraryReaderImpl>()
val tempMarks = mutableSetOf<LibraryReaderImpl>()
private fun List<KonanLibraryReader>.topoSort(): List<KonanLibraryReader> {
var sorted = mutableListOf<KonanLibraryReader>()
val visited = mutableSetOf<KonanLibraryReader>()
val tempMarks = mutableSetOf<KonanLibraryReader>()
fun visit(node: LibraryReaderImpl, result: MutableList<LibraryReaderImpl>) {
fun visit(node: KonanLibraryReader, result: MutableList<KonanLibraryReader>) {
if (visited.contains(node)) return
if (tempMarks.contains(node)) error("Cyclic dependency in library graph.")
tempMarks.add(node)
@@ -16,10 +16,10 @@
package org.jetbrains.kotlin.backend.konan.optimizations
import org.jetbrains.kotlin.backend.common.reportWarning
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.serialization.konan.DefaultKonanModuleDescriptorFactory
import sun.misc.Unsafe
import kotlin.reflect.KClass
import kotlin.reflect.full.memberProperties
@@ -948,7 +948,8 @@ internal object DFGSerializer {
}
if (libraryDataFlowGraph != null) {
val module = DataFlowIR.Module(library.moduleDescriptor(specifics))
val module = DataFlowIR.Module(
DefaultKonanModuleDescriptorFactory.createModuleDescriptor(library, specifics))
val reader = ArraySlice(libraryDataFlowGraph)
val dataLayoutHash = reader.readLong()
val expectedHash = computeDataLayoutHash(Module::class)
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.tasks.createSynthesizedInvokes
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.descriptors.*
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.isError
@@ -1,46 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.NameResolver
import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.serialization.deserialization.ClassData
import org.jetbrains.kotlin.serialization.deserialization.ClassDataFinder
import org.jetbrains.kotlin.serialization.deserialization.getClassId
class KonanClassDataFinder(
private val fragment: KonanProtoBuf.LinkDataPackageFragment,
private val nameResolver: NameResolver
) : ClassDataFinder {
override fun findClassData(classId: ClassId): ClassData? {
val proto = fragment.classes
val nameList = proto.getClassNameList()
val index = nameList.indexOfFirst {
nameResolver.getClassId(it) == classId }
if (index == -1)
error("Could not find serialized class $classId")
val foundClass = proto.getClasses(index) ?: error("Could not find data for serialized class $classId")
/* TODO: binary version supposed to be read from protobuf. */
return ClassData(nameResolver, foundClass, KonanMetadataVersion.INSTANCE, SourceElement.NO_SOURCE)
}
}
@@ -1,32 +0,0 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
class KonanMetadataVersion(vararg numbers: Int): BinaryVersion(*numbers){
override fun isCompatible(): Boolean = this.major == 1 && this.minor == 0
companion object {
@JvmField
val INSTANCE = KonanMetadataVersion(1, 0, 0)
@JvmField
val INVALID_VERSION = KonanMetadataVersion()
}
}
@@ -1,94 +0,0 @@
/*
* Copyright 2010-2017 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.serialization.deserialization.DeserializedPackageFragment
import org.jetbrains.kotlin.metadata.deserialization.NameResolverImpl
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.serialization.deserialization.DeserializationComponents
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPackageMemberScope
import org.jetbrains.kotlin.serialization.deserialization.getClassId
import org.jetbrains.kotlin.serialization.deserialization.getName
import org.jetbrains.kotlin.storage.StorageManager
class KonanPackageFragment(
val fqNameString: String,
val reader: KonanLibraryReader,
storageManager: StorageManager, module: ModuleDescriptor
) : DeserializedPackageFragment(FqName(fqNameString), storageManager, module) {
lateinit var components: DeserializationComponents
override fun initialize(components: DeserializationComponents) {
this.components = components
}
// The proto field is lazy so that we can load only needed
// packages from the library.
private val protoForNames: KonanProtoBuf.LinkDataPackageFragment by lazy {
parsePackageFragment(reader.packageMetadata(fqNameString))
}
val proto: KonanProtoBuf.LinkDataPackageFragment get() = protoForNames.also {
reader.markPackageAccessed(fqNameString)
}
private val nameResolver by lazy {
NameResolverImpl(protoForNames.getStringTable(), protoForNames.getNameTable())
}
override val classDataFinder by lazy {
KonanClassDataFinder(proto, nameResolver)
}
private val memberScope_ by lazy {
/* TODO: we fake proto binary versioning for now. */
DeserializedPackageMemberScope(this, proto.getPackage(),
nameResolver, KonanMetadataVersion.INSTANCE,/* containerSource = */ null,
components, { loadClassNames() })
}
override fun getMemberScope(): DeserializedPackageMemberScope = memberScope_
private val classifierNames by lazy {
val result = mutableSetOf<Name>()
result.addAll(loadClassNames())
protoForNames.getPackage().typeAliasList.mapTo(result) { nameResolver.getName(it.name) }
result
}
fun hasTopLevelClassifier(name: Name): Boolean = name in classifierNames
private fun loadClassNames(): Collection<Name> {
val classNameList = protoForNames.getClasses().getClassNameList()
val names = classNameList.mapNotNull {
val classId = nameResolver.getClassId(it)
val shortName = classId.getShortClassName()
if (!classId.isNestedClass) shortName else null
}
return names
}
}
@@ -17,32 +17,18 @@
package org.jetbrains.kotlin.backend.konan.serialization
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.createInteropLibrary
import org.jetbrains.kotlin.backend.konan.descriptors.isExpectMember
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryReader
import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
import org.jetbrains.kotlin.descriptors.konan.createKonanModuleDescriptor
import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf.*
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.descriptorUtil.module
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.storage.LockBasedStorageManager
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
/*
* This is Konan specific part of public descriptor
@@ -55,92 +41,6 @@ import org.jetbrains.kotlin.types.SimpleType
* with MemberDeserializer class.
*/
/* ------------ Deserializer part ------------------------------------------*/
object NullFlexibleTypeDeserializer : FlexibleTypeDeserializer {
override fun create(proto: ProtoBuf.Type, flexibleId: String,
lowerBound: SimpleType, upperBound: SimpleType): KotlinType {
error("Illegal use of flexible type deserializer.")
}
}
fun createKonanPackageFragmentProvider(
reader: KonanLibraryReader,
fragmentNames: List<String>,
storageManager: StorageManager, module: ModuleDescriptor,
configuration: DeserializationConfiguration): PackageFragmentProvider {
val packageFragments = fragmentNames.map{
KonanPackageFragment(it, reader, storageManager, module)
}
val interopLibrary = createInteropLibrary(reader)
val syntheticInteropPackageFragments =
interopLibrary?.createSyntheticPackages(module, packageFragments) ?: emptyList()
val provider = PackageFragmentProviderImpl(packageFragments + syntheticInteropPackageFragments)
val notFoundClasses = NotFoundClasses(storageManager, module)
val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(module, notFoundClasses, KonanSerializerProtocol)
val components = DeserializationComponents(
storageManager, module, configuration,
DeserializedClassDataFinder(provider),
annotationAndConstantLoader,
provider,
LocalClassifierTypeSettings.Default,
ErrorReporter.DO_NOTHING,
LookupTracker.DO_NOTHING, NullFlexibleTypeDeserializer,
emptyList(), notFoundClasses, ContractDeserializer.DEFAULT, extensionRegistryLite = KonanSerializerProtocol.extensionRegistry )
for (packageFragment in packageFragments) {
packageFragment.initialize(components)
}
return provider
}
public fun parsePackageFragment(packageData: ByteArray): LinkDataPackageFragment =
LinkDataPackageFragment.parseFrom(packageData,
KonanSerializerProtocol.extensionRegistry)
public fun parseModuleHeader(libraryData: ByteArray): LinkDataLibrary =
LinkDataLibrary.parseFrom(libraryData,
KonanSerializerProtocol.extensionRegistry)
public fun emptyPackages(libraryData: ByteArray)
= parseModuleHeader(libraryData).emptyPackageList
internal fun deserializeModule(languageVersionSettings: LanguageVersionSettings,
reader: KonanLibraryReader): ModuleDescriptorImpl {
val libraryProto = parseModuleHeader(reader.moduleHeaderData)
val moduleName = libraryProto.moduleName
val storageManager = LockBasedStorageManager()
val moduleDescriptor = createKonanModuleDescriptor(
Name.special(moduleName), storageManager,
origin = DeserializedKonanModuleOrigin(reader)
)
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
val provider = createKonanPackageFragmentProvider(
reader,
libraryProto.packageFragmentNameList,
storageManager,
moduleDescriptor, deserializationConfiguration)
moduleDescriptor.initialize(provider)
return moduleDescriptor
}
/* ------------ Serializer part ------------------------------------------*/
internal class KonanSerializationUtil(val context: Context, metadataVersion: BinaryVersion) {
val serializerExtension = KonanSerializerExtension(context, metadataVersion)
@@ -22,10 +22,9 @@ import org.jetbrains.kotlin.metadata.deserialization.BinaryVersion
import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
import org.jetbrains.kotlin.metadata.serialization.MutableVersionRequirementTable
import org.jetbrains.kotlin.protobuf.ExtensionRegistryLite
import org.jetbrains.kotlin.serialization.KonanDescriptorSerializer
import org.jetbrains.kotlin.serialization.KotlinSerializerExtensionBase
import org.jetbrains.kotlin.serialization.SerializerExtensionProtocol
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
import org.jetbrains.kotlin.types.KotlinType
internal class KonanSerializerExtension(val context: Context, override val metadataVersion: BinaryVersion) :
@@ -105,22 +104,6 @@ internal class KonanSerializerExtension(val context: Context, override val metad
}
}
object KonanSerializerProtocol : SerializerExtensionProtocol(
ExtensionRegistryLite.newInstance().apply {
KonanProtoBuf.registerAllExtensions(this)
},
KonanProtoBuf.packageFqName,
KonanProtoBuf.constructorAnnotation,
KonanProtoBuf.classAnnotation,
KonanProtoBuf.functionAnnotation,
KonanProtoBuf.propertyAnnotation,
KonanProtoBuf.enumEntryAnnotation,
KonanProtoBuf.compileTimeValue,
KonanProtoBuf.parameterAnnotation,
KonanProtoBuf.typeAnnotation,
KonanProtoBuf.typeParameterAnnotation
)
internal interface IrAwareExtension {
fun serializeInlineBody(descriptor: FunctionDescriptor, serializer: KonanDescriptorSerializer): String
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.metadata.ProtoBuf
import org.jetbrains.kotlin.metadata.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.*
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassDescriptor
import org.jetbrains.kotlin.serialization.konan.KonanMetadataVersion
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
// This class knows how to construct contexts for
// MemberDeserializer to deserialize descriptors declared in IR.
@@ -52,6 +52,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.parents
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedClassConstructorDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedPropertyDescriptor
import org.jetbrains.kotlin.serialization.deserialization.descriptors.DeserializedSimpleFunctionDescriptor
import org.jetbrains.kotlin.serialization.konan.KonanSerializerProtocol
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeProjectionImpl
import org.jetbrains.kotlin.types.TypeSubstitutor