backend: add workaround for blacklisted Cloneable in ClassDeserializer
This commit is contained in:
committed by
SvyatoslavScherbina
parent
401ac0567e
commit
d259f29352
+60
@@ -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<BuiltInsPackageFragment>().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<ClassDescriptor> =
|
||||||
|
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())
|
||||||
|
}
|
||||||
|
}
|
||||||
+3
@@ -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).
|
// stdlib comes first to override declarations from builtIns (even when they are requested from builtIns).
|
||||||
builtInsModule.setDependencies(stdlib, builtInsModule)
|
builtInsModule.setDependencies(stdlib, builtInsModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getClassDescriptorFactories() =
|
||||||
|
super.getClassDescriptorFactories() + KonanBuiltInClassDescriptorFactory(storageManager, builtInsModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
object KonanPlatform : TargetPlatform("Konan") {
|
object KonanPlatform : TargetPlatform("Konan") {
|
||||||
|
|||||||
Reference in New Issue
Block a user