KLIB reader: uniform API for obtaining module descriptors from Kotlin/Native libraries (#1932)
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
buildscript {
|
||||
ext.rootBuildDirectory = file('../..')
|
||||
|
||||
apply from: "$rootBuildDirectory/gradle/loadRootProperties.gradle"
|
||||
apply from: "$rootBuildDirectory/gradle/kotlinGradlePlugin.gradle"
|
||||
}
|
||||
|
||||
apply plugin: 'kotlin'
|
||||
|
||||
group = 'org.jetbrains.kotlin'
|
||||
version = konanVersion
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven {
|
||||
url kotlinCompilerRepo
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main.kotlin {
|
||||
srcDir 'src/main/kotlin'
|
||||
}
|
||||
}
|
||||
|
||||
jar {
|
||||
archiveName = "${project.name}.jar"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
url buildKotlinCompilerRepo
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$buildKotlinVersion"
|
||||
compile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion"
|
||||
compile "org.jetbrains.kotlin:kotlin-compiler:$kotlinVersion"
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
rootProject.name = "konan.descriptors"
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
package org.jetbrains.kotlin.descriptors.konan
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
fun createKonanModuleDescriptor(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
origin: KonanModuleOrigin
|
||||
): ModuleDescriptorImpl {
|
||||
val builtIns = KonanBuiltIns(storageManager)
|
||||
|
||||
val moduleDescriptor = createKonanModuleDescriptor(name, storageManager, builtIns, origin)
|
||||
|
||||
builtIns.builtInsModule = moduleDescriptor
|
||||
// It is mostly correct because any module should depend on stdlib.
|
||||
|
||||
return moduleDescriptor
|
||||
}
|
||||
|
||||
fun createKonanModuleDescriptor(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns,
|
||||
origin: KonanModuleOrigin
|
||||
) = ModuleDescriptorImpl(
|
||||
name, storageManager, builtIns,
|
||||
capabilities = mapOf(KonanModuleOrigin.CAPABILITY to origin)
|
||||
)
|
||||
|
||||
private val STDLIB_MODULE_NAME = Name.special("<$KONAN_STDLIB_NAME>")
|
||||
|
||||
fun ModuleDescriptor.isKonanStdlib() = name == STDLIB_MODULE_NAME
|
||||
-113
@@ -1,113 +0,0 @@
|
||||
package org.jetbrains.kotlin.descriptors.konan.interop
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.createKonanModuleDescriptor
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
/**
|
||||
* Creates module which "contains" forward declarations.
|
||||
* Note: this module should be unique per compilation and should always be the last dependency of any module.
|
||||
*/
|
||||
fun createForwardDeclarationsModule(builtIns: KotlinBuiltIns, storageManager: StorageManager): ModuleDescriptorImpl {
|
||||
val module = createKonanModuleDescriptor(
|
||||
Name.special("<forward declarations>"),
|
||||
storageManager,
|
||||
builtIns,
|
||||
origin = SyntheticModulesOrigin
|
||||
)
|
||||
|
||||
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind = ClassKind.CLASS) =
|
||||
ForwardDeclarationsPackageFragmentDescriptor(
|
||||
storageManager,
|
||||
module,
|
||||
fqName,
|
||||
Name.identifier(supertypeName),
|
||||
classKind
|
||||
)
|
||||
|
||||
val packageFragmentProvider = PackageFragmentProviderImpl(
|
||||
listOf(
|
||||
createPackage(InteropFqNames.cNamesStructs, "COpaque"),
|
||||
createPackage(InteropFqNames.objCNamesClasses, "ObjCObjectBase"),
|
||||
createPackage(InteropFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
|
||||
)
|
||||
)
|
||||
|
||||
module.initialize(packageFragmentProvider)
|
||||
module.setDependencies(module)
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
/**
|
||||
* Package fragment which creates descriptors for forward declarations on demand.
|
||||
*/
|
||||
private class ForwardDeclarationsPackageFragmentDescriptor(
|
||||
storageManager: StorageManager,
|
||||
module: ModuleDescriptor, fqName: FqName, supertypeName: Name, classKind: ClassKind
|
||||
) : PackageFragmentDescriptorImpl(module, fqName) {
|
||||
|
||||
private val memberScope = object : MemberScopeImpl() {
|
||||
|
||||
private val declarations = storageManager.createMemoizedFunction(this::createDeclaration)
|
||||
|
||||
private val supertype by storageManager.createLazyValue {
|
||||
val descriptor = builtIns.builtInsModule.getPackage(InteropFqNames.packageName)
|
||||
.memberScope
|
||||
.getContributedClassifier(supertypeName, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
|
||||
descriptor.defaultType
|
||||
}
|
||||
|
||||
private fun createDeclaration(name: Name): ClassDescriptor {
|
||||
return ClassDescriptorImpl(
|
||||
this@ForwardDeclarationsPackageFragmentDescriptor,
|
||||
name, Modality.FINAL, classKind,
|
||||
listOf(supertype), SourceElement.NO_SOURCE, false, LockBasedStorageManager.NO_LOCKS
|
||||
).apply {
|
||||
this.initialize(MemberScope.Empty, emptySet(), null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = declarations(name)
|
||||
|
||||
override fun printScopeStructure(p: Printer) {
|
||||
p.println(this::class.java.simpleName, "{}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMemberScope(): MemberScope = memberScope
|
||||
}
|
||||
|
||||
object InteropFqNames {
|
||||
|
||||
const val cPointerName = "CPointer"
|
||||
const val nativePointedName = "NativePointed"
|
||||
|
||||
val packageName = FqName("kotlinx.cinterop")
|
||||
|
||||
val cPointer = packageName.child(Name.identifier(cPointerName)).toUnsafe()
|
||||
val nativePointed = packageName.child(Name.identifier(nativePointedName)).toUnsafe()
|
||||
|
||||
val cNames = FqName("cnames")
|
||||
val cNamesStructs = cNames.child(Name.identifier("structs"))
|
||||
|
||||
val objCNames = FqName("objcnames")
|
||||
val objCNamesClasses = objCNames.child(Name.identifier("classes"))
|
||||
val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
|
||||
}
|
||||
@@ -34,6 +34,8 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile "org.jetbrains.kotlin:konan.descriptors:$konanVersion"
|
||||
compile "org.jetbrains.kotlin:kotlin-stdlib:$buildKotlinVersion"
|
||||
compile "org.jetbrains.kotlin:kotlin-native-shared:$konanVersion"
|
||||
compile "org.jetbrains.kotlin:kotlin-compiler:$kotlinVersion"
|
||||
compile "org.jetbrains.kotlin:konan.metadata:$konanVersion"
|
||||
}
|
||||
|
||||
-1
@@ -9,4 +9,3 @@ class KonanBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageMana
|
||||
override fun getSuspendFunction(parameterCount: Int) =
|
||||
getBuiltInClassByName(Name.identifier("SuspendFunction$parameterCount"))
|
||||
}
|
||||
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.kotlin.descriptors.konan
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
interface KonanModuleDescriptorFactory {
|
||||
|
||||
/**
|
||||
* Base method for creation of any Kotlin/Native [ModuleDescriptor].
|
||||
*/
|
||||
fun createDescriptor(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns,
|
||||
origin: KonanModuleOrigin,
|
||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
||||
): ModuleDescriptorImpl
|
||||
|
||||
/**
|
||||
* Please use this method with care: As far as it creates an instance of [KotlinBuiltIns] it should be
|
||||
* normally used for creation of the very first (e.g. "stdlib") module in the set of created modules.
|
||||
*/
|
||||
fun createDescriptorAndNewBuiltIns(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
origin: KonanModuleOrigin,
|
||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap()
|
||||
): ModuleDescriptorImpl
|
||||
}
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
package org.jetbrains.kotlin.descriptors.konan
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.konan.library.KONAN_STDLIB_NAME
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
private val STDLIB_MODULE_NAME = Name.special("<$KONAN_STDLIB_NAME>")
|
||||
|
||||
fun ModuleDescriptor.isKonanStdlib() = name == STDLIB_MODULE_NAME
|
||||
+2
-2
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.kotlin.descriptors.konan
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
|
||||
sealed class KonanModuleOrigin {
|
||||
|
||||
@@ -11,8 +12,7 @@ sealed class KonanModuleOrigin {
|
||||
|
||||
sealed class CompiledKonanModuleOrigin: KonanModuleOrigin()
|
||||
|
||||
// FIXME(ddol): replace `Any` by `KonanLibrary` when ready
|
||||
class DeserializedKonanModuleOrigin(val library: Any) : CompiledKonanModuleOrigin()
|
||||
class DeserializedKonanModuleOrigin(val library: KonanLibrary) : CompiledKonanModuleOrigin()
|
||||
|
||||
object CurrentKonanModuleOrigin: CompiledKonanModuleOrigin()
|
||||
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
package org.jetbrains.kotlin.descriptors.konan.impl
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleOrigin
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
internal object KonanModuleDescriptorFactoryImpl: KonanModuleDescriptorFactory {
|
||||
|
||||
override fun createDescriptor(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns,
|
||||
origin: KonanModuleOrigin,
|
||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||
) = ModuleDescriptorImpl(
|
||||
name,
|
||||
storageManager,
|
||||
builtIns,
|
||||
capabilities = customCapabilities + mapOf(KonanModuleOrigin.CAPABILITY to origin))
|
||||
|
||||
override fun createDescriptorAndNewBuiltIns(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
origin: KonanModuleOrigin,
|
||||
customCapabilities: Map<ModuleDescriptor.Capability<*>, Any?>
|
||||
): ModuleDescriptorImpl {
|
||||
|
||||
val builtIns = KonanBuiltIns(storageManager)
|
||||
|
||||
val moduleDescriptor = createDescriptor(name, storageManager, builtIns, origin, customCapabilities)
|
||||
builtIns.builtInsModule = moduleDescriptor
|
||||
|
||||
return moduleDescriptor
|
||||
}
|
||||
}
|
||||
@@ -22,15 +22,15 @@ interface KonanLibrary {
|
||||
val libraryName: String
|
||||
val libraryFile: File
|
||||
|
||||
// whether this library is default (provided by Kotlin/Native distribution)
|
||||
// Whether this library is default (provided by Kotlin/Native distribution)?
|
||||
val isDefault: Boolean
|
||||
|
||||
// properties:
|
||||
// Properties:
|
||||
val manifestProperties: Properties
|
||||
val abiVersion: String
|
||||
val linkerOpts: List<String>
|
||||
|
||||
// paths:
|
||||
// Paths:
|
||||
val bitcodePaths: List<String>
|
||||
val includedPaths: List<String>
|
||||
|
||||
|
||||
+3
-1
@@ -3,7 +3,9 @@ package org.jetbrains.kotlin.konan.library
|
||||
import org.jetbrains.kotlin.konan.file.File
|
||||
import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
// This scheme describes the Kotlin/Native Library (klib) layout.
|
||||
/**
|
||||
* This scheme describes the Kotlin/Native Library (KLIB) layout.
|
||||
*/
|
||||
interface KonanLibraryLayout {
|
||||
|
||||
val libraryName: String
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.konan.target.KonanTarget
|
||||
|
||||
fun File.unpackZippedKonanLibraryTo(newDir: File) {
|
||||
|
||||
// first run validity checks for the given KLIB file
|
||||
// First, run validity checks for the given KLIB file.
|
||||
zippedKonanLibraryChecks(this)
|
||||
|
||||
if (newDir.exists) {
|
||||
|
||||
+4
-4
@@ -33,10 +33,10 @@ private class UnzippedKonanLibraryLayout(override val libDir: File, override val
|
||||
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.
|
||||
/**
|
||||
* 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 [ZippedKonanLibraryLayout].
|
||||
*/
|
||||
private class FileExtractor(zippedLibraryLayout: KonanLibraryLayout): KonanLibraryLayout by zippedLibraryLayout {
|
||||
|
||||
override val manifestFile: File by lazy { extract(super.manifestFile) }
|
||||
|
||||
+4
-4
@@ -13,15 +13,15 @@ interface PackageAccessedHandler {
|
||||
*/
|
||||
interface KonanResolvedLibrary: PackageAccessedHandler {
|
||||
|
||||
// the library itself
|
||||
// The library itself.
|
||||
val library: KonanLibrary
|
||||
|
||||
// dependencies on other libraries
|
||||
// Dependencies on other libraries.
|
||||
val resolvedDependencies: List<KonanResolvedLibrary>
|
||||
|
||||
// if it's needed to linker
|
||||
// Whether it is needed to linker.
|
||||
val isNeededForLink: Boolean
|
||||
|
||||
// is provided by the distribution
|
||||
// Is provided by the distribution?
|
||||
val isDefault: Boolean
|
||||
}
|
||||
|
||||
+2
-2
@@ -73,8 +73,8 @@ internal class KonanLibraryResolverImpl(
|
||||
|
||||
val rootLibraries = this.map { KonanResolvedLibraryImpl(it) }
|
||||
|
||||
// as far as the list of root libraries is known from the very beginning, the result can be
|
||||
// constructed from the very beginning as well
|
||||
// As far as the list of root libraries is known from the very beginning, the result can be
|
||||
// constructed from the very beginning as well.
|
||||
val result = KonanLibraryResolverResultImpl(rootLibraries)
|
||||
|
||||
val cache = mutableMapOf<File, KonanResolvedLibrary>()
|
||||
|
||||
+2
-2
@@ -3,14 +3,14 @@ package org.jetbrains.kotlin.konan.library.resolver.impl
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.KonanResolvedLibrary
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.serialization.konan.emptyPackages
|
||||
import org.jetbrains.kotlin.serialization.konan.parseModuleHeader
|
||||
|
||||
internal class KonanResolvedLibraryImpl(
|
||||
override val library: KonanLibrary
|
||||
): KonanResolvedLibrary {
|
||||
|
||||
private val _resolvedDependencies = mutableListOf<KonanResolvedLibrary>()
|
||||
private val _emptyPackages by lazy { emptyPackages(library.moduleHeaderData) }
|
||||
private val _emptyPackages by lazy { parseModuleHeader(library.moduleHeaderData).emptyPackageList }
|
||||
|
||||
override val resolvedDependencies: List<KonanResolvedLibrary>
|
||||
get() = _resolvedDependencies
|
||||
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.jetbrains.kotlin.konan.utils
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
||||
import org.jetbrains.kotlin.descriptors.konan.impl.KonanModuleDescriptorFactoryImpl
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedModuleDescriptorFactory
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedPackageFragmentsFactory
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptorsFactory
|
||||
import org.jetbrains.kotlin.serialization.konan.impl.KonanDeserializedModuleDescriptorFactoryImpl
|
||||
import org.jetbrains.kotlin.serialization.konan.impl.KonanDeserializedPackageFragmentsFactoryImpl
|
||||
import org.jetbrains.kotlin.serialization.konan.impl.KonanResolvedModuleDescriptorsFactoryImpl
|
||||
|
||||
/**
|
||||
* The default Kotlin/Native factories.
|
||||
*/
|
||||
object KonanFactories {
|
||||
|
||||
/**
|
||||
* The default [KonanModuleDescriptorFactory] factory instance.
|
||||
*/
|
||||
val DefaultDescriptorFactory: KonanModuleDescriptorFactory = KonanModuleDescriptorFactoryImpl
|
||||
|
||||
/**
|
||||
* The default [KonanDeserializedPackageFragmentsFactory] factory instance.
|
||||
*/
|
||||
val DefaultPackageFragmentsFactory: KonanDeserializedPackageFragmentsFactory =
|
||||
KonanDeserializedPackageFragmentsFactoryImpl
|
||||
|
||||
/**
|
||||
* The default [KonanDeserializedModuleDescriptorFactory] factory instance.
|
||||
*/
|
||||
val DefaultDeserializedDescriptorFactory: KonanDeserializedModuleDescriptorFactory =
|
||||
createDefaultKonanDeserializedModuleDescriptorFactory(
|
||||
DefaultDescriptorFactory, DefaultPackageFragmentsFactory)
|
||||
|
||||
/**
|
||||
* The default [KonanResolvedModuleDescriptorsFactory] factory instance.
|
||||
*/
|
||||
val DefaultResolvedDescriptorsFactory: KonanResolvedModuleDescriptorsFactory =
|
||||
createDefaultKonanResolvedModuleDescriptorsFactory(DefaultDeserializedDescriptorFactory)
|
||||
|
||||
fun createDefaultKonanDeserializedModuleDescriptorFactory(
|
||||
descriptorFactory: KonanModuleDescriptorFactory,
|
||||
packageFragmentsFactory: KonanDeserializedPackageFragmentsFactory
|
||||
): KonanDeserializedModuleDescriptorFactory =
|
||||
KonanDeserializedModuleDescriptorFactoryImpl(descriptorFactory, packageFragmentsFactory)
|
||||
|
||||
fun createDefaultKonanResolvedModuleDescriptorsFactory(
|
||||
moduleDescriptorFactory: KonanDeserializedModuleDescriptorFactory
|
||||
): KonanResolvedModuleDescriptorsFactory = KonanResolvedModuleDescriptorsFactoryImpl(moduleDescriptorFactory)
|
||||
}
|
||||
+4
-6
@@ -2,10 +2,8 @@ package org.jetbrains.kotlin.serialization.konan
|
||||
|
||||
import org.jetbrains.kotlin.metadata.konan.KonanProtoBuf
|
||||
|
||||
fun parsePackageFragment(packageData: ByteArray): KonanProtoBuf.LinkDataPackageFragment =
|
||||
KonanProtoBuf.LinkDataPackageFragment.parseFrom(packageData, KonanSerializerProtocol.extensionRegistry)
|
||||
fun parsePackageFragment(packageMetadata: ByteArray): KonanProtoBuf.LinkDataPackageFragment =
|
||||
KonanProtoBuf.LinkDataPackageFragment.parseFrom(packageMetadata, KonanSerializerProtocol.extensionRegistry)
|
||||
|
||||
fun parseModuleHeader(libraryData: ByteArray): KonanProtoBuf.LinkDataLibrary =
|
||||
KonanProtoBuf.LinkDataLibrary.parseFrom(libraryData, KonanSerializerProtocol.extensionRegistry)
|
||||
|
||||
fun emptyPackages(libraryData: ByteArray) = parseModuleHeader(libraryData).emptyPackageList
|
||||
fun parseModuleHeader(libraryMetadata: ByteArray): KonanProtoBuf.LinkDataLibrary =
|
||||
KonanProtoBuf.LinkDataLibrary.parseFrom(libraryMetadata, KonanSerializerProtocol.extensionRegistry)
|
||||
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
package org.jetbrains.kotlin.serialization.konan
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
interface KonanDeserializedModuleDescriptorFactory {
|
||||
|
||||
val descriptorFactory: KonanModuleDescriptorFactory
|
||||
val packageFragmentsFactory: KonanDeserializedPackageFragmentsFactory
|
||||
|
||||
fun createDescriptor(
|
||||
library: KonanLibrary,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns,
|
||||
packageAccessedHandler: PackageAccessedHandler? = null
|
||||
): ModuleDescriptorImpl
|
||||
|
||||
/**
|
||||
* Please use this method with care: As far as it creates an instance of [KotlinBuiltIns] it should be
|
||||
* normally used for creation of the very first (e.g. "stdlib") module in the set of created modules.
|
||||
*/
|
||||
fun createDescriptorAndNewBuiltIns(
|
||||
library: KonanLibrary,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
storageManager: StorageManager,
|
||||
packageAccessedHandler: PackageAccessedHandler? = null
|
||||
): ModuleDescriptorImpl
|
||||
}
|
||||
+24
@@ -0,0 +1,24 @@
|
||||
package org.jetbrains.kotlin.serialization.konan
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
interface KonanDeserializedPackageFragmentsFactory {
|
||||
|
||||
fun createDeserializedPackageFragments(
|
||||
library: KonanLibrary,
|
||||
packageFragmentNames: List<String>,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
packageAccessedHandler: PackageAccessedHandler?,
|
||||
storageManager: StorageManager
|
||||
): List<KonanPackageFragment>
|
||||
|
||||
fun createSyntheticPackageFragments(
|
||||
library: KonanLibrary,
|
||||
deserializedPackageFragments: List<KonanPackageFragment>,
|
||||
moduleDescriptor: ModuleDescriptor
|
||||
): List<PackageFragmentDescriptor>
|
||||
}
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
package org.jetbrains.kotlin.serialization.konan
|
||||
|
||||
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.descriptors.konan.interop.InteropFqNames
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
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.konan.library.resolver.PackageAccessedHandler
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
// FIXME(ddol): this is a temporary solution, to be refactored into some global resolution context
|
||||
interface KonanModuleDescriptorFactory {
|
||||
|
||||
fun createModuleDescriptor(
|
||||
library: KonanLibrary,
|
||||
specifics: LanguageVersionSettings,
|
||||
packageAccessedHandler: PackageAccessedHandler? = null,
|
||||
storageManager: StorageManager = LockBasedStorageManager()
|
||||
): ModuleDescriptor
|
||||
}
|
||||
|
||||
object DefaultKonanModuleDescriptorFactory: KonanModuleDescriptorFactory {
|
||||
|
||||
override fun createModuleDescriptor(
|
||||
library: KonanLibrary,
|
||||
specifics: LanguageVersionSettings,
|
||||
packageAccessedHandler: PackageAccessedHandler?,
|
||||
storageManager: StorageManager
|
||||
): ModuleDescriptorImpl {
|
||||
|
||||
val libraryProto = parseModuleHeader(library.moduleHeaderData)
|
||||
|
||||
val moduleName = libraryProto.moduleName
|
||||
|
||||
val moduleDescriptor = createKonanModuleDescriptor(
|
||||
Name.special(moduleName),
|
||||
storageManager,
|
||||
origin = DeserializedKonanModuleOrigin(library)
|
||||
)
|
||||
val deserializationConfiguration = CompilerDeserializationConfiguration(specifics)
|
||||
|
||||
val provider = createPackageFragmentProvider(
|
||||
library,
|
||||
packageAccessedHandler,
|
||||
libraryProto.packageFragmentNameList,
|
||||
storageManager,
|
||||
moduleDescriptor,
|
||||
deserializationConfiguration)
|
||||
|
||||
moduleDescriptor.initialize(provider)
|
||||
|
||||
return moduleDescriptor
|
||||
}
|
||||
|
||||
private fun createPackageFragmentProvider(
|
||||
library: KonanLibrary,
|
||||
packageAccessedHandler: PackageAccessedHandler?,
|
||||
fragmentNames: List<String>,
|
||||
storageManager: StorageManager,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
configuration: DeserializationConfiguration
|
||||
): PackageFragmentProvider {
|
||||
|
||||
val deserializedPackageFragments = fragmentNames.map{
|
||||
KonanPackageFragment(FqName(it), library, packageAccessedHandler, storageManager, moduleDescriptor)
|
||||
}
|
||||
|
||||
val syntheticPackageFragments = getSyntheticPackageFragments(
|
||||
library,
|
||||
moduleDescriptor,
|
||||
deserializedPackageFragments)
|
||||
|
||||
val provider = PackageFragmentProviderImpl(deserializedPackageFragments + syntheticPackageFragments)
|
||||
|
||||
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
|
||||
|
||||
val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(
|
||||
moduleDescriptor,
|
||||
notFoundClasses,
|
||||
KonanSerializerProtocol)
|
||||
|
||||
val components = DeserializationComponents(
|
||||
storageManager,
|
||||
moduleDescriptor,
|
||||
configuration,
|
||||
DeserializedClassDataFinder(provider),
|
||||
annotationAndConstantLoader,
|
||||
provider,
|
||||
LocalClassifierTypeSettings.Default,
|
||||
ErrorReporter.DO_NOTHING,
|
||||
LookupTracker.DO_NOTHING,
|
||||
NullFlexibleTypeDeserializer,
|
||||
emptyList(),
|
||||
notFoundClasses,
|
||||
ContractDeserializer.DEFAULT,
|
||||
extensionRegistryLite = KonanSerializerProtocol.extensionRegistry)
|
||||
|
||||
for (packageFragment in deserializedPackageFragments) {
|
||||
packageFragment.initialize(components)
|
||||
}
|
||||
|
||||
return provider
|
||||
}
|
||||
|
||||
private fun getSyntheticPackageFragments(
|
||||
library: KonanLibrary,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
konanPackageFragments: List<KonanPackageFragment>
|
||||
): List<PackageFragmentDescriptor> {
|
||||
|
||||
if (!library.isInterop) return emptyList()
|
||||
|
||||
val packageFqName = library.packageFqName
|
||||
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
|
||||
|
||||
val exportForwardDeclarations = library.exportForwardDeclarations
|
||||
|
||||
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, moduleDescriptor, fqName)
|
||||
}
|
||||
// TODO: use separate namespaces for structs, enums, Objective-C protocols etc.
|
||||
|
||||
result.add(ExportedForwardDeclarationsPackageFragmentDescriptor(moduleDescriptor, packageFqName, exportForwardDeclarations))
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
+32
@@ -0,0 +1,32 @@
|
||||
package org.jetbrains.kotlin.serialization.konan
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
interface KonanResolvedModuleDescriptorsFactory {
|
||||
|
||||
val moduleDescriptorFactory: KonanDeserializedModuleDescriptorFactory
|
||||
|
||||
fun createResolved(
|
||||
resolvedLibraries: KonanLibraryResolveResult,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns?,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
customAction: ((KonanLibrary, ModuleDescriptorImpl) -> Unit)? = null
|
||||
): KonanResolvedModuleDescriptors
|
||||
}
|
||||
|
||||
class KonanResolvedModuleDescriptors(
|
||||
|
||||
val resolvedDescriptors: List<ModuleDescriptorImpl>,
|
||||
|
||||
/**
|
||||
* This is a module which "contains" forward declarations.
|
||||
* Note: this module should be unique per compilation and should always be the last dependency of any module.
|
||||
*/
|
||||
val forwardDeclarationsModule: ModuleDescriptorImpl
|
||||
)
|
||||
+120
@@ -0,0 +1,120 @@
|
||||
package org.jetbrains.kotlin.serialization.konan.impl
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.NotFoundClasses
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentProviderImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKonanModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleDescriptorFactory
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.CompilerDeserializationConfiguration
|
||||
import org.jetbrains.kotlin.serialization.deserialization.*
|
||||
import org.jetbrains.kotlin.serialization.konan.*
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
|
||||
internal class KonanDeserializedModuleDescriptorFactoryImpl(
|
||||
override val descriptorFactory: KonanModuleDescriptorFactory,
|
||||
override val packageFragmentsFactory: KonanDeserializedPackageFragmentsFactory
|
||||
): KonanDeserializedModuleDescriptorFactory {
|
||||
|
||||
override fun createDescriptor(
|
||||
library: KonanLibrary,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns,
|
||||
packageAccessedHandler: PackageAccessedHandler?
|
||||
) = createDescriptorOptionalBuiltIns(library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler)
|
||||
|
||||
override fun createDescriptorAndNewBuiltIns(
|
||||
library: KonanLibrary,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
storageManager: StorageManager,
|
||||
packageAccessedHandler: PackageAccessedHandler?
|
||||
) = createDescriptorOptionalBuiltIns(library, languageVersionSettings, storageManager, null, packageAccessedHandler)
|
||||
|
||||
private fun createDescriptorOptionalBuiltIns(
|
||||
library: KonanLibrary,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns?,
|
||||
packageAccessedHandler: PackageAccessedHandler?
|
||||
): ModuleDescriptorImpl {
|
||||
|
||||
val libraryProto = parseModuleHeader(library.moduleHeaderData)
|
||||
|
||||
val moduleName = Name.special(libraryProto.moduleName)
|
||||
val moduleOrigin = DeserializedKonanModuleOrigin(library)
|
||||
|
||||
val moduleDescriptor = if (builtIns != null )
|
||||
descriptorFactory.createDescriptor(moduleName, storageManager, builtIns, moduleOrigin)
|
||||
else
|
||||
descriptorFactory.createDescriptorAndNewBuiltIns(moduleName, storageManager, moduleOrigin)
|
||||
|
||||
val deserializationConfiguration = CompilerDeserializationConfiguration(languageVersionSettings)
|
||||
|
||||
val provider = createPackageFragmentProvider(
|
||||
library,
|
||||
packageAccessedHandler,
|
||||
libraryProto.packageFragmentNameList,
|
||||
storageManager,
|
||||
moduleDescriptor,
|
||||
deserializationConfiguration)
|
||||
|
||||
moduleDescriptor.initialize(provider)
|
||||
|
||||
return moduleDescriptor
|
||||
}
|
||||
|
||||
private fun createPackageFragmentProvider(
|
||||
library: KonanLibrary,
|
||||
packageAccessedHandler: PackageAccessedHandler?,
|
||||
packageFragmentNames: List<String>,
|
||||
storageManager: StorageManager,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
configuration: DeserializationConfiguration
|
||||
): PackageFragmentProvider {
|
||||
|
||||
val deserializedPackageFragments = packageFragmentsFactory.createDeserializedPackageFragments(
|
||||
library, packageFragmentNames, moduleDescriptor, packageAccessedHandler, storageManager)
|
||||
|
||||
val syntheticPackageFragments = packageFragmentsFactory.createSyntheticPackageFragments(
|
||||
library, deserializedPackageFragments, moduleDescriptor)
|
||||
|
||||
val provider = PackageFragmentProviderImpl(deserializedPackageFragments + syntheticPackageFragments)
|
||||
|
||||
val notFoundClasses = NotFoundClasses(storageManager, moduleDescriptor)
|
||||
|
||||
val annotationAndConstantLoader = AnnotationAndConstantLoaderImpl(
|
||||
moduleDescriptor,
|
||||
notFoundClasses,
|
||||
KonanSerializerProtocol)
|
||||
|
||||
val components = DeserializationComponents(
|
||||
storageManager,
|
||||
moduleDescriptor,
|
||||
configuration,
|
||||
DeserializedClassDataFinder(provider),
|
||||
annotationAndConstantLoader,
|
||||
provider,
|
||||
LocalClassifierTypeSettings.Default,
|
||||
ErrorReporter.DO_NOTHING,
|
||||
LookupTracker.DO_NOTHING,
|
||||
NullFlexibleTypeDeserializer,
|
||||
emptyList(),
|
||||
notFoundClasses,
|
||||
ContractDeserializer.DEFAULT,
|
||||
extensionRegistryLite = KonanSerializerProtocol.extensionRegistry)
|
||||
|
||||
for (packageFragment in deserializedPackageFragments) {
|
||||
packageFragment.initialize(components)
|
||||
}
|
||||
|
||||
return provider
|
||||
}
|
||||
}
|
||||
+48
-1
@@ -1,16 +1,63 @@
|
||||
package org.jetbrains.kotlin.serialization.konan
|
||||
package org.jetbrains.kotlin.serialization.konan.impl
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.ClassifierDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
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.konan.library.resolver.PackageAccessedHandler
|
||||
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.serialization.konan.KonanDeserializedPackageFragmentsFactory
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanPackageFragment
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
|
||||
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
|
||||
internal object KonanDeserializedPackageFragmentsFactoryImpl: KonanDeserializedPackageFragmentsFactory {
|
||||
|
||||
override fun createDeserializedPackageFragments(
|
||||
library: KonanLibrary,
|
||||
packageFragmentNames: List<String>,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
packageAccessedHandler: PackageAccessedHandler?,
|
||||
storageManager: StorageManager
|
||||
) = packageFragmentNames.map {
|
||||
KonanPackageFragment(FqName(it), library, packageAccessedHandler, storageManager, moduleDescriptor)
|
||||
}
|
||||
|
||||
override fun createSyntheticPackageFragments(
|
||||
library: KonanLibrary,
|
||||
deserializedPackageFragments: List<KonanPackageFragment>,
|
||||
moduleDescriptor: ModuleDescriptor
|
||||
): List<PackageFragmentDescriptor> {
|
||||
|
||||
if (!library.isInterop) return emptyList()
|
||||
|
||||
val mainPackageFqName = library.packageFqName
|
||||
?: error("Inconsistent manifest: interop library ${library.libraryName} should have `package` specified")
|
||||
val exportForwardDeclarations = library.exportForwardDeclarations
|
||||
|
||||
val aliasedPackageFragments = deserializedPackageFragments.filter { it.fqName == mainPackageFqName }
|
||||
|
||||
val result = mutableListOf<PackageFragmentDescriptor>()
|
||||
listOf(ForwardDeclarationsFqNames.cNamesStructs, ForwardDeclarationsFqNames.objCNamesClasses, ForwardDeclarationsFqNames.objCNamesProtocols).mapTo(result) { fqName ->
|
||||
ClassifierAliasingPackageFragmentDescriptor(aliasedPackageFragments, moduleDescriptor, fqName)
|
||||
}
|
||||
|
||||
result.add(ExportedForwardDeclarationsPackageFragmentDescriptor(moduleDescriptor, mainPackageFqName, exportForwardDeclarations))
|
||||
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The package fragment to export forward declarations from interop package namespace, i.e.
|
||||
* redirect "$pkg.$name" to e.g. "cnames.structs.$name".
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
package org.jetbrains.kotlin.serialization.konan.impl
|
||||
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.impl.PackageFragmentDescriptorImpl
|
||||
import org.jetbrains.kotlin.descriptors.konan.KonanModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.SyntheticModulesOrigin
|
||||
import org.jetbrains.kotlin.incremental.components.LookupLocation
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibrary
|
||||
import org.jetbrains.kotlin.konan.library.resolver.KonanLibraryResolveResult
|
||||
import org.jetbrains.kotlin.konan.library.resolver.PackageAccessedHandler
|
||||
import org.jetbrains.kotlin.konan.util.profile
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScopeImpl
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanDeserializedModuleDescriptorFactory
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptors
|
||||
import org.jetbrains.kotlin.serialization.konan.KonanResolvedModuleDescriptorsFactory
|
||||
import org.jetbrains.kotlin.storage.LockBasedStorageManager
|
||||
import org.jetbrains.kotlin.storage.StorageManager
|
||||
import org.jetbrains.kotlin.storage.getValue
|
||||
import org.jetbrains.kotlin.utils.Printer
|
||||
|
||||
class KonanResolvedModuleDescriptorsFactoryImpl(
|
||||
override val moduleDescriptorFactory: KonanDeserializedModuleDescriptorFactory
|
||||
): KonanResolvedModuleDescriptorsFactory {
|
||||
|
||||
override fun createResolved(
|
||||
resolvedLibraries: KonanLibraryResolveResult,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns?,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
customAction: ((KonanLibrary, ModuleDescriptorImpl) -> Unit)?
|
||||
): KonanResolvedModuleDescriptors {
|
||||
|
||||
val moduleDescriptors = mutableListOf<ModuleDescriptorImpl>()
|
||||
@Suppress("NAME_SHADOWING")
|
||||
var builtIns = builtIns
|
||||
|
||||
// Build module descriptors.
|
||||
resolvedLibraries.forEach { library, packageAccessedHandler ->
|
||||
profile("Loading ${library.libraryName}") {
|
||||
|
||||
// MutableModuleContext needs ModuleDescriptorImpl, rather than ModuleDescriptor.
|
||||
val moduleDescriptor = createDescriptorOptionalBuiltsIns(
|
||||
library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler)
|
||||
builtIns = moduleDescriptor.builtIns
|
||||
moduleDescriptors.add(moduleDescriptor)
|
||||
|
||||
customAction?.invoke(library, moduleDescriptor)
|
||||
}
|
||||
}
|
||||
|
||||
val forwardDeclarationsModule = createForwardDeclarationsModule(builtIns, storageManager)
|
||||
|
||||
// Set inter-dependencies between module descriptors, add forwarding declarations module.
|
||||
for (module in moduleDescriptors) {
|
||||
// Yes, just to all of them.
|
||||
module.setDependencies(moduleDescriptors + forwardDeclarationsModule)
|
||||
}
|
||||
|
||||
return KonanResolvedModuleDescriptors(moduleDescriptors, forwardDeclarationsModule)
|
||||
}
|
||||
|
||||
private fun createForwardDeclarationsModule(
|
||||
builtIns: KotlinBuiltIns?,
|
||||
storageManager: StorageManager): ModuleDescriptorImpl {
|
||||
|
||||
val name = Name.special("<forward declarations>")
|
||||
val module = createDescriptorOptionalBuiltsIns(name, storageManager, builtIns, SyntheticModulesOrigin)
|
||||
|
||||
fun createPackage(fqName: FqName, supertypeName: String, classKind: ClassKind) =
|
||||
ForwardDeclarationsPackageFragmentDescriptor(
|
||||
storageManager,
|
||||
module,
|
||||
fqName,
|
||||
Name.identifier(supertypeName),
|
||||
classKind)
|
||||
|
||||
val packageFragmentProvider = PackageFragmentProviderImpl(
|
||||
listOf(
|
||||
createPackage(ForwardDeclarationsFqNames.cNamesStructs, "COpaque", ClassKind.CLASS),
|
||||
createPackage(ForwardDeclarationsFqNames.objCNamesClasses, "ObjCObjectBase", ClassKind.CLASS),
|
||||
createPackage(ForwardDeclarationsFqNames.objCNamesProtocols, "ObjCObject", ClassKind.INTERFACE)
|
||||
)
|
||||
)
|
||||
|
||||
module.initialize(packageFragmentProvider)
|
||||
module.setDependencies(module)
|
||||
|
||||
return module
|
||||
}
|
||||
|
||||
private fun createDescriptorOptionalBuiltsIns(
|
||||
name: Name,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns?,
|
||||
moduleOrigin: KonanModuleOrigin
|
||||
) = if (builtIns != null)
|
||||
moduleDescriptorFactory.descriptorFactory.createDescriptor(name, storageManager, builtIns, moduleOrigin)
|
||||
else
|
||||
moduleDescriptorFactory.descriptorFactory.createDescriptorAndNewBuiltIns(name, storageManager, moduleOrigin)
|
||||
|
||||
private fun createDescriptorOptionalBuiltsIns(
|
||||
library: KonanLibrary,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
storageManager: StorageManager,
|
||||
builtIns: KotlinBuiltIns?,
|
||||
packageAccessedHandler: PackageAccessedHandler?
|
||||
) = if (builtIns != null)
|
||||
moduleDescriptorFactory.createDescriptor(library, languageVersionSettings, storageManager, builtIns, packageAccessedHandler)
|
||||
else
|
||||
moduleDescriptorFactory.createDescriptorAndNewBuiltIns(library, languageVersionSettings, storageManager, packageAccessedHandler)
|
||||
}
|
||||
|
||||
/**
|
||||
* Package fragment which creates descriptors for forward declarations on demand.
|
||||
*/
|
||||
private class ForwardDeclarationsPackageFragmentDescriptor(
|
||||
storageManager: StorageManager,
|
||||
module: ModuleDescriptor,
|
||||
fqName: FqName,
|
||||
supertypeName: Name,
|
||||
classKind: ClassKind
|
||||
) : PackageFragmentDescriptorImpl(module, fqName) {
|
||||
|
||||
private val memberScope = object : MemberScopeImpl() {
|
||||
|
||||
private val declarations = storageManager.createMemoizedFunction(this::createDeclaration)
|
||||
|
||||
private val supertype by storageManager.createLazyValue {
|
||||
val descriptor = builtIns.builtInsModule.getPackage(ForwardDeclarationsFqNames.packageName)
|
||||
.memberScope
|
||||
.getContributedClassifier(supertypeName, NoLookupLocation.FROM_BACKEND) as ClassDescriptor
|
||||
|
||||
descriptor.defaultType
|
||||
}
|
||||
|
||||
private fun createDeclaration(name: Name): ClassDescriptor {
|
||||
return ClassDescriptorImpl(
|
||||
this@ForwardDeclarationsPackageFragmentDescriptor,
|
||||
name,
|
||||
Modality.FINAL,
|
||||
classKind,
|
||||
listOf(supertype),
|
||||
SourceElement.NO_SOURCE,
|
||||
false,
|
||||
LockBasedStorageManager.NO_LOCKS
|
||||
).apply {
|
||||
this.initialize(MemberScope.Empty, emptySet(), null)
|
||||
}
|
||||
}
|
||||
|
||||
override fun getContributedClassifier(name: Name, location: LookupLocation) = declarations(name)
|
||||
|
||||
override fun printScopeStructure(p: Printer) {
|
||||
p.println(this::class.java.simpleName, "{}")
|
||||
}
|
||||
}
|
||||
|
||||
override fun getMemberScope(): MemberScope = memberScope
|
||||
}
|
||||
|
||||
// FIXME(ddol): decouple and move interop-specific logic back to Kotlin/Native.
|
||||
internal object ForwardDeclarationsFqNames {
|
||||
|
||||
val packageName = FqName("kotlinx.cinterop")
|
||||
|
||||
val cNames = FqName("cnames")
|
||||
val cNamesStructs = cNames.child(Name.identifier("structs"))
|
||||
|
||||
val objCNames = FqName("objcnames")
|
||||
val objCNamesClasses = objCNames.child(Name.identifier("classes"))
|
||||
val objCNamesProtocols = objCNames.child(Name.identifier("protocols"))
|
||||
}
|
||||
Reference in New Issue
Block a user