diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanBuiltInClassDescriptorFactory.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanBuiltInClassDescriptorFactory.kt new file mode 100644 index 00000000000..b938037a3a8 --- /dev/null +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanBuiltInClassDescriptorFactory.kt @@ -0,0 +1,60 @@ +package org.jetbrains.kotlin.backend.konan + +import org.jetbrains.kotlin.builtins.BuiltInsPackageFragment +import org.jetbrains.kotlin.builtins.CloneableClassScope +import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.descriptors.* +import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorImpl +import org.jetbrains.kotlin.name.ClassId +import org.jetbrains.kotlin.name.FqName +import org.jetbrains.kotlin.name.Name +import org.jetbrains.kotlin.serialization.deserialization.ClassDescriptorFactory +import org.jetbrains.kotlin.storage.StorageManager +import org.jetbrains.kotlin.storage.getValue + +/** + * Note: this class is copy-pasted from [org.jetbrains.kotlin.builtins.JvmBuiltInClassDescriptorFactory]. + */ +class KonanBuiltInClassDescriptorFactory( + storageManager: StorageManager, + private val moduleDescriptor: ModuleDescriptor, + private val computeContainingDeclaration: (ModuleDescriptor) -> DeclarationDescriptor = { module -> + module.getPackage(KOTLIN_FQ_NAME).fragments.filterIsInstance().first() + } +) : ClassDescriptorFactory { + + /** + * Workaround for `kotlin.Cloneable` deserialization: it is manually blacklisted in `ClassDeserializer`, + * so apply the same approach as on JVM, i.e. create the descriptor synthetically on demand: + */ + private val cloneable by storageManager.createLazyValue { + ClassDescriptorImpl( + computeContainingDeclaration(moduleDescriptor), + CLONEABLE_NAME, Modality.ABSTRACT, ClassKind.INTERFACE, listOf(moduleDescriptor.builtIns.anyType), + SourceElement.NO_SOURCE, /* isExternal = */ false + ).apply { + initialize(CloneableClassScope(storageManager, this), emptySet(), null) + } + } + + override fun shouldCreateClass(packageFqName: FqName, name: Name): Boolean = + name == CLONEABLE_NAME && packageFqName == KOTLIN_FQ_NAME + + override fun createClass(classId: ClassId): ClassDescriptor? = + when (classId) { + CLONEABLE_CLASS_ID -> cloneable + else -> null + } + + override fun getAllContributedClassesIfPossible(packageFqName: FqName): Collection = + when (packageFqName) { + KOTLIN_FQ_NAME -> setOf(cloneable) + else -> emptySet() + } + + companion object { + private val KOTLIN_FQ_NAME = KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME + private val CLONEABLE_NAME = KotlinBuiltIns.FQ_NAMES.cloneable.shortName() + val CLONEABLE_CLASS_ID = ClassId.topLevel(KotlinBuiltIns.FQ_NAMES.cloneable.toSafe()) + } +} diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPlatform.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPlatform.kt index 491be3747a4..2b3fb5b9917 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPlatform.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPlatform.kt @@ -56,6 +56,9 @@ class KonanBuiltIns(storageManager: StorageManager) : KotlinBuiltIns(storageMana // stdlib comes first to override declarations from builtIns (even when they are requested from builtIns). builtInsModule.setDependencies(stdlib, builtInsModule) } + + override fun getClassDescriptorFactories() = + super.getClassDescriptorFactories() + KonanBuiltInClassDescriptorFactory(storageManager, builtInsModule) } object KonanPlatform : TargetPlatform("Konan") {