[WASM] Implementation typeOf support

This commit is contained in:
Igor Yakovlev
2021-10-29 15:14:26 +02:00
committed by TeamCityServer
parent 39a389c49a
commit ee7f4c7278
31 changed files with 258 additions and 198 deletions
@@ -6,18 +6,14 @@ package kotlin.reflect.wasm.internal
import kotlin.reflect.*
import kotlin.wasm.internal.TypeInfoData
import kotlin.wasm.internal.getInterfaceImplId
import kotlin.wasm.internal.getSuperTypeId
import kotlin.wasm.internal.isInterface
internal object NothingKClassImpl : KClass<Nothing> {
override val simpleName: String = "Nothing"
override val qualifiedName: String get() = "kotlin.Nothing"
override fun isInstance(value: Any?): Boolean = false
override fun equals(other: Any?): Boolean = other === this
override fun hashCode(): Int = -1
}
internal object ErrorKClass : KClass<Nothing> {
@@ -25,10 +21,6 @@ internal object ErrorKClass : KClass<Nothing> {
override val qualifiedName: String get() = error("Unknown qualifiedName for ErrorKClass")
override fun isInstance(value: Any?): Boolean = error("Can's check isInstance on ErrorKClass")
override fun equals(other: Any?): Boolean = other === this
override fun hashCode(): Int = 0
}
internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<T> {
@@ -45,11 +37,12 @@ internal class KClassImpl<T : Any>(private val typeData: TypeInfoData) : KClass<
return false
}
override fun isInstance(value: Any?): Boolean =
value != null && (checkSuperTypeInstance(value) || getInterfaceImplId(value, typeData.typeId) != -1)
override fun isInstance(value: Any?): Boolean = value?.let {
if (typeData.isInterface) isInterface(it, typeData.typeId) else checkSuperTypeInstance(it)
} ?: false
override fun equals(other: Any?): Boolean =
(this === other) || (other is KClassImpl<*> && other.typeInfo == typeData.typeId)
(this === other) || (other is KClassImpl<*> && other.typeData.isInterface == typeData.isInterface && other.typeData.typeId == typeData.typeId)
override fun hashCode(): Int = typeData.typeId
}
@@ -0,0 +1,14 @@
/*
* Copyright 2010-2021 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.*
internal class KTypeImpl(
override val classifier: KClassifier?,
override val arguments: List<KTypeProjection>,
override val isMarkedNullable: Boolean
) : KType
@@ -0,0 +1,17 @@
/*
* Copyright 2010-2019 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.*
internal data class KTypeParameterImpl(
override val name: String,
override val upperBounds: List<KType>,
override val variance: KVariance,
override val isReified: Boolean
) : KTypeParameter {
override fun toString(): String = name
}
@@ -14,6 +14,7 @@ internal object PrimitiveClasses {
val anyClass = wasmGetKClass<Any>()
val numberClass = wasmGetKClass<Number>()
val longClass = wasmGetKClass<Long>()
val booleanClass = wasmGetKClass<Boolean>()
val byteClass = wasmGetKClass<Byte>()
val shortClass = wasmGetKClass<Short>()
@@ -9,21 +9,8 @@ package kotlin.wasm.internal
import kotlin.reflect.*
import kotlin.reflect.wasm.internal.*
internal fun <T : Any> getKClass(typeInfoData: TypeInfoData): KClass<T> {
// return if (js("Array").isArray(jClass)) {
// getKClassM(jClass.unsafeCast<Array<JsClass<T>>>())
// } else {
// getKClass1(jClass.unsafeCast<JsClass<T>>())
// }
return getKClass1(typeInfoData)
}
internal fun <T : Any> getKClassM(jClasses: Array<TypeInfoData>): KClass<T> = when (jClasses.size) {
1 -> getKClass1(jClasses[0])
0 -> NothingKClassImpl as KClass<T>
else -> ErrorKClass as KClass<T>
}
internal fun <T : Any> getKClass(typeInfoData: TypeInfoData): KClass<T> =
KClassImpl(typeInfoData)
internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
when (e) {
@@ -33,6 +20,7 @@ internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
is Float -> PrimitiveClasses.floatClass
is Boolean -> PrimitiveClasses.booleanClass
is Double -> PrimitiveClasses.doubleClass
is Long -> PrimitiveClasses.longClass
is Number -> PrimitiveClasses.numberClass
is BooleanArray -> PrimitiveClasses.booleanArrayClass
@@ -45,17 +33,33 @@ internal fun <T : Any> getKClassFromExpression(e: T): KClass<T> =
is DoubleArray -> PrimitiveClasses.doubleArrayClass
is KClass<*> -> KClass::class
is Array<*> -> PrimitiveClasses.arrayClass
is Function<*> -> PrimitiveClasses.functionClass(0) //TODO
else -> {
getKClass1(getTypeInfoTypeDataByPtr(e.typeInfo))
}
else -> getKClass(getTypeInfoTypeDataByPtr(e.typeInfo))
} as KClass<T>
internal fun <T : Any> getKClass1(infoData: TypeInfoData): KClass<T> {
return KClassImpl(infoData)
}
@Suppress("REIFIED_TYPE_PARAMETER_NO_INLINE")
internal inline fun <reified T : Any> wasmGetKClass(): KClass<T> =
KClassImpl(wasmGetTypeInfoData<T>())
internal fun createKType(classifier: KClassifier, arguments: Array<KTypeProjection>, isMarkedNullable: Boolean): KType =
KTypeImpl(classifier, arguments.asList(), isMarkedNullable)
internal fun createKTypeParameter(name: String, upperBounds: Array<KType>, variance: String): KTypeParameter {
val kVariance = when (variance) {
"in" -> KVariance.IN
"out" -> KVariance.OUT
else -> KVariance.INVARIANT
}
return KTypeParameterImpl(name, upperBounds.asList(), kVariance, false)
}
internal fun getStarKTypeProjection(): KTypeProjection =
KTypeProjection.STAR
internal fun createCovariantKTypeProjection(type: KType): KTypeProjection =
KTypeProjection.covariant(type)
internal fun createInvariantKTypeProjection(type: KType): KTypeProjection =
KTypeProjection.invariant(type)
internal fun createContravariantKTypeProjection(type: KType): KTypeProjection =
KTypeProjection.contravariant(type)