[Wasm] Support for Associated Objects feature
This commit is contained in:
committed by
Space Team
parent
993334e5e4
commit
b8f797af00
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package kotlin.reflect
|
||||
|
||||
import kotlin.wasm.internal.wasmClassId
|
||||
import kotlin.wasm.internal.findAssociatedObject
|
||||
|
||||
/**
|
||||
* The experimental marker for associated objects API.
|
||||
*
|
||||
* Any usage of a declaration annotated with `@ExperimentalAssociatedObjects` must be accepted either by
|
||||
* annotating that usage with the [OptIn] annotation, e.g. `@OptIn(ExperimentalAssociatedObjects::class)`,
|
||||
* or by using the compiler argument `-opt-in=kotlin.reflect.ExperimentalAssociatedObjects`.
|
||||
*/
|
||||
@RequiresOptIn(level = RequiresOptIn.Level.ERROR)
|
||||
@Retention(value = AnnotationRetention.BINARY)
|
||||
public annotation class ExperimentalAssociatedObjects
|
||||
|
||||
/**
|
||||
* Makes the annotated annotation class an associated object key.
|
||||
*
|
||||
* An associated object key annotation should have single [KClass] parameter.
|
||||
* When applied to a class with reference to an object declaration as an argument, it binds
|
||||
* the object to the class, making this binding discoverable at runtime using [findAssociatedObject].
|
||||
*/
|
||||
@ExperimentalAssociatedObjects
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
@Target(AnnotationTarget.ANNOTATION_CLASS)
|
||||
public annotation class AssociatedObjectKey
|
||||
|
||||
/**
|
||||
* If [T] is an @[AssociatedObjectKey]-annotated annotation class and [this] class is annotated with @[T] (`S::class`),
|
||||
* returns object `S`.
|
||||
*
|
||||
* Otherwise returns `null`.
|
||||
*/
|
||||
@ExperimentalAssociatedObjects
|
||||
@Suppress("NON_PUBLIC_CALL_FROM_PUBLIC_INLINE")
|
||||
public inline fun <reified T : Annotation> KClass<*>.findAssociatedObject(): Any? =
|
||||
findAssociatedObject(this, wasmClassId<T>())
|
||||
@@ -23,7 +23,7 @@ internal object ErrorKClass : KClass<Nothing> {
|
||||
override fun isInstance(value: Any?): Boolean = error("Can's check isInstance on ErrorKClass")
|
||||
}
|
||||
|
||||
internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<T> {
|
||||
internal class KClassImpl<T : Any>(internal val typeData: TypeInfoData) : KClass<T> {
|
||||
override val simpleName: String get() = typeData.typeName
|
||||
override val qualifiedName: String =
|
||||
if (typeData.packageName.isEmpty()) typeData.typeName else "${typeData.packageName}.${typeData.typeName}"
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2010-2023 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package kotlin.wasm.internal
|
||||
|
||||
import kotlin.reflect.wasm.internal.KClassImpl
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
internal var associatedObjects: Map<ULong, Any>? = null
|
||||
|
||||
@PublishedApi
|
||||
internal fun findAssociatedObject(klass: KClass<*>, key: Int): Any? {
|
||||
val klassId = (klass as? KClassImpl<*>)?.typeData?.typeId ?: return null
|
||||
|
||||
val map = associatedObjects ?: run {
|
||||
val newMap: MutableMap<ULong, Any> = mutableMapOf()
|
||||
initAssociatedObjects(newMap)
|
||||
associatedObjects = newMap
|
||||
newMap
|
||||
}
|
||||
|
||||
return map[packIntoULong(klassId, key)]
|
||||
}
|
||||
|
||||
internal fun packIntoULong(a: Int, b: Int): ULong =
|
||||
(a.toUInt().toULong() shl Int.SIZE_BITS) or b.toUInt().toULong()
|
||||
|
||||
internal fun addAssociatedObject(
|
||||
mapToInit: MutableMap<ULong, Any>,
|
||||
klassId: Int,
|
||||
keyId: Int,
|
||||
instance: Any
|
||||
) {
|
||||
mapToInit[packIntoULong(klassId, keyId)] = instance
|
||||
}
|
||||
|
||||
internal fun initAssociatedObjects(@Suppress("UNUSED_PARAMETER") mapToInit: MutableMap<ULong, Any>) {
|
||||
// Init implicitly with AssociatedObjectsLowering
|
||||
// addAssociatedObject(mapToInit, ...)
|
||||
}
|
||||
Reference in New Issue
Block a user