[WASM] Implementation typeOf support
This commit is contained in:
committed by
TeamCityServer
parent
39a389c49a
commit
ee7f4c7278
@@ -415,7 +415,7 @@ fun usefulDeclarations(
|
||||
}
|
||||
}
|
||||
}
|
||||
context.intrinsics.jsGetKClassFromExpression -> {
|
||||
context.reflectionSymbols.getKClassFromExpression -> {
|
||||
val ref = expression.getTypeArgument(0)?.classOrNull ?: context.irBuiltIns.anyClass
|
||||
referencedJsClassesFromExpressions += ref.owner
|
||||
}
|
||||
|
||||
+1
-5
@@ -30,16 +30,12 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
interface JsCommonBackendContext : CommonBackendContext {
|
||||
override val mapping: JsMapping
|
||||
|
||||
val intrinsics: Intrinsics
|
||||
|
||||
val dynamicType: IrDynamicType
|
||||
val reflectionSymbols: ReflectionSymbols
|
||||
|
||||
val inlineClassesUtils: InlineClassesUtils
|
||||
|
||||
val coroutineSymbols: JsCommonCoroutineSymbols
|
||||
|
||||
val primitiveClassesObject: IrClassSymbol
|
||||
|
||||
val catchAllThrowableType: IrType
|
||||
get() = irBuiltIns.throwableType
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import org.jetbrains.kotlin.ir.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.isLong
|
||||
import org.jetbrains.kotlin.ir.util.constructors
|
||||
@@ -21,21 +22,7 @@ import org.jetbrains.kotlin.psi2ir.findSingleFunction
|
||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
|
||||
import java.util.*
|
||||
|
||||
interface Intrinsics {
|
||||
val jsGetKClassFromExpression: IrSimpleFunctionSymbol
|
||||
val jsGetKClass: IrSimpleFunctionSymbol
|
||||
val jsClass: IrSimpleFunctionSymbol
|
||||
val createKType: IrSimpleFunctionSymbol?
|
||||
val createDynamicKType: IrSimpleFunctionSymbol?
|
||||
val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||
val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val arrayLiteral: IrSimpleFunctionSymbol
|
||||
}
|
||||
|
||||
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) : Intrinsics {
|
||||
class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendContext) {
|
||||
|
||||
// TODO: Should we drop operator intrinsics in favor of IrDynamicOperatorExpression?
|
||||
|
||||
@@ -184,10 +171,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsInvokeSuspendSuperTypeWithReceiverAndParam =
|
||||
getInternalWithoutPackage("kotlin.coroutines.intrinsics.invokeSuspendSuperTypeWithReceiverAndParam")
|
||||
|
||||
override val jsGetKClass = getInternalWithoutPackage("getKClass")
|
||||
override val jsGetKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
||||
override val jsClass = getInternalFunction("jsClassIntrinsic")
|
||||
|
||||
val jsNumberRangeToNumber = getInternalFunction("numberRangeToNumber")
|
||||
val jsNumberRangeToLong = getInternalFunction("numberRangeToLong")
|
||||
|
||||
@@ -249,7 +232,25 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
val jsPrimitiveArrayIteratorFunctions =
|
||||
PrimitiveType.values().associate { it to getInternalFunction("${it.typeName.asString().toLowerCaseAsciiOnly()}ArrayIterator") }
|
||||
|
||||
override val arrayLiteral = getInternalFunction("arrayLiteral")
|
||||
val jsClass = getInternalFunction("jsClassIntrinsic")
|
||||
val arrayLiteral: IrSimpleFunctionSymbol = getInternalFunction("arrayLiteral")
|
||||
|
||||
internal inner class JsReflectionSymbols : ReflectionSymbols {
|
||||
override val createKType = getInternalWithoutPackageOrNull("createKType")
|
||||
override val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType")
|
||||
override val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter")
|
||||
override val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection")
|
||||
override val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection")
|
||||
override val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection")
|
||||
override val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection")
|
||||
override val getKClass = getInternalWithoutPackage("getKClass")
|
||||
override val getKClassFromExpression = getInternalWithoutPackage("getKClassFromExpression")
|
||||
override val primitiveClassesObject = context.getIrClass(FqName("kotlin.reflect.js.internal.PrimitiveClasses"))
|
||||
override val kTypeClass: IrClassSymbol = context.getIrClass(FqName("kotlin.reflect.KType"))
|
||||
override val getClassData: IrSimpleFunctionSymbol get() = jsClass
|
||||
}
|
||||
|
||||
internal val reflectionSymbols: JsReflectionSymbols = JsReflectionSymbols()
|
||||
|
||||
val primitiveToTypedArrayMap = EnumMap(
|
||||
mapOf(
|
||||
@@ -261,14 +262,6 @@ class JsIntrinsics(private val irBuiltIns: IrBuiltIns, val context: JsIrBackendC
|
||||
)
|
||||
)
|
||||
|
||||
override val createKType = getInternalWithoutPackageOrNull("createKType")
|
||||
override val createDynamicKType = getInternalWithoutPackageOrNull("createDynamicKType")
|
||||
override val createKTypeParameter = getInternalWithoutPackageOrNull("createKTypeParameter")
|
||||
override val getStarKTypeProjection = getInternalWithoutPackageOrNull("getStarKTypeProjection")
|
||||
override val createCovariantKTypeProjection = getInternalWithoutPackageOrNull("createCovariantKTypeProjection")
|
||||
override val createInvariantKTypeProjection = getInternalWithoutPackageOrNull("createInvariantKTypeProjection")
|
||||
override val createContravariantKTypeProjection = getInternalWithoutPackageOrNull("createContravariantKTypeProjection")
|
||||
|
||||
val primitiveToSizeConstructor =
|
||||
PrimitiveType.values().associate { type ->
|
||||
type to (primitiveToTypedArrayMap[type]?.let {
|
||||
|
||||
@@ -157,8 +157,9 @@ class JsIrBackendContext(
|
||||
|
||||
private val internalPackage = module.getPackage(JS_PACKAGE_FQNAME)
|
||||
|
||||
override val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||
override val intrinsics = JsIntrinsics(irBuiltIns, this)
|
||||
val dynamicType: IrDynamicType = IrDynamicTypeImpl(null, emptyList(), Variance.INVARIANT)
|
||||
val intrinsics: JsIntrinsics = JsIntrinsics(irBuiltIns, this)
|
||||
override val reflectionSymbols: ReflectionSymbols get() = intrinsics.reflectionSymbols
|
||||
|
||||
override val catchAllThrowableType: IrType
|
||||
get() = dynamicType
|
||||
@@ -284,16 +285,12 @@ class JsIrBackendContext(
|
||||
val errorCodeSymbol: IrSimpleFunctionSymbol? =
|
||||
if (errorPolicy.allowErrors) symbolTable.referenceSimpleFunction(getJsInternalFunction("errorCode")) else null
|
||||
|
||||
override val primitiveClassesObject = getIrClass(FqName("kotlin.reflect.js.internal.PrimitiveClasses"))
|
||||
|
||||
val throwableClass = getIrClass(JsIrBackendContext.KOTLIN_PACKAGE_FQN.child(Name.identifier("Throwable")))
|
||||
|
||||
val primitiveCompanionObjects = primitivesWithImplicitCompanionObject().associateWith {
|
||||
getIrClass(JS_INTERNAL_PACKAGE_FQNAME.child(Name.identifier("${it.identifier}CompanionObject")))
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Top-level functions forced to be loaded
|
||||
|
||||
|
||||
@@ -355,7 +352,7 @@ class JsIrBackendContext(
|
||||
internal fun getProperty(fqName: FqName): PropertyDescriptor =
|
||||
findProperty(module.getPackage(fqName.parent()).memberScope, fqName.shortName()).single()
|
||||
|
||||
private fun getIrClass(fqName: FqName): IrClassSymbol = symbolTable.referenceClass(getClass(fqName))
|
||||
internal fun getIrClass(fqName: FqName): IrClassSymbol = symbolTable.referenceClass(getClass(fqName))
|
||||
|
||||
internal fun getJsInternalFunction(name: String): SimpleFunctionDescriptor =
|
||||
findFunctions(internalPackage.memberScope, Name.identifier(name)).singleOrNull() ?: error("Internal function '$name' not found")
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* 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 org.jetbrains.kotlin.ir.backend.js
|
||||
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
|
||||
interface ReflectionSymbols {
|
||||
val getKClassFromExpression: IrSimpleFunctionSymbol
|
||||
val getKClass: IrSimpleFunctionSymbol
|
||||
val getClassData: IrSimpleFunctionSymbol
|
||||
val createKType: IrSimpleFunctionSymbol?
|
||||
val createDynamicKType: IrSimpleFunctionSymbol?
|
||||
val createKTypeParameter: IrSimpleFunctionSymbol?
|
||||
val getStarKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createCovariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createInvariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val createContravariantKTypeProjection: IrSimpleFunctionSymbol?
|
||||
val primitiveClassesObject: IrClassSymbol
|
||||
val kTypeClass: IrClassSymbol
|
||||
}
|
||||
+37
-29
@@ -8,9 +8,10 @@ package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.ir.Symbols
|
||||
import org.jetbrains.kotlin.backend.common.ir.createArrayOfExpression
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.backend.js.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.toJsArrayLiteral
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
@@ -25,21 +26,22 @@ import org.jetbrains.kotlin.types.*
|
||||
|
||||
class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLoweringPass {
|
||||
|
||||
private val reflectionSymbols get() = context.reflectionSymbols
|
||||
|
||||
private val primitiveClassProperties by lazy {
|
||||
primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
||||
reflectionSymbols.primitiveClassesObject.owner.declarations.filterIsInstance<IrProperty>()
|
||||
}
|
||||
|
||||
private val primitiveClassFunctionClass by lazy {
|
||||
primitiveClassesObject.owner.declarations
|
||||
reflectionSymbols.primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>()
|
||||
.find { it.name == Name.identifier("functionClass") }!!
|
||||
}
|
||||
|
||||
private val primitiveClassesObject = context.primitiveClassesObject
|
||||
|
||||
private fun primitiveClassProperty(name: String) =
|
||||
primitiveClassProperties.singleOrNull { it.name == Name.identifier(name) }?.getter
|
||||
?: primitiveClassesObject.owner.declarations.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||
?: reflectionSymbols.primitiveClassesObject.owner.declarations
|
||||
.filterIsInstance<IrSimpleFunction>().single { it.name == Name.special("<get-$name>") }
|
||||
|
||||
private val finalPrimitiveClasses by lazy {
|
||||
mapOf(
|
||||
@@ -80,14 +82,17 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
if (primitiveKClass != null)
|
||||
return JsIrBuilder.buildBlock(returnType, listOf(argument, primitiveKClass))
|
||||
|
||||
return JsIrBuilder.buildCall(context.intrinsics.jsGetKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
||||
return JsIrBuilder.buildCall(reflectionSymbols.getKClassFromExpression, returnType, listOf(typeArgument)).apply {
|
||||
putValueArgument(0, argument)
|
||||
}
|
||||
}
|
||||
|
||||
private fun getPrimitiveClass(target: IrSimpleFunction, returnType: IrType) =
|
||||
JsIrBuilder.buildCall(target.symbol, returnType).apply {
|
||||
dispatchReceiver = JsIrBuilder.buildGetObjectValue(primitiveClassesObject.defaultType, primitiveClassesObject)
|
||||
dispatchReceiver = JsIrBuilder.buildGetObjectValue(
|
||||
type = reflectionSymbols.primitiveClassesObject.defaultType,
|
||||
classSymbol = reflectionSymbols.primitiveClassesObject
|
||||
)
|
||||
}
|
||||
|
||||
private fun getFinalPrimitiveKClass(returnType: IrType, typeArgument: IrType): IrCall? {
|
||||
@@ -118,7 +123,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
}
|
||||
|
||||
private fun callGetKClass(
|
||||
returnType: IrType = context.intrinsics.jsGetKClass.owner.returnType,
|
||||
returnType: IrType = reflectionSymbols.getKClass.owner.returnType,
|
||||
typeArgument: IrType
|
||||
): IrCall {
|
||||
val primitiveKClass =
|
||||
@@ -127,15 +132,15 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
if (primitiveKClass != null)
|
||||
return primitiveKClass
|
||||
|
||||
return JsIrBuilder.buildCall(context.intrinsics.jsGetKClass, returnType, listOf(typeArgument))
|
||||
return JsIrBuilder.buildCall(reflectionSymbols.getKClass, returnType, listOf(typeArgument))
|
||||
.apply {
|
||||
putValueArgument(0, callJsClass(typeArgument))
|
||||
putValueArgument(0, callGetClassByType(typeArgument))
|
||||
}
|
||||
}
|
||||
|
||||
private fun callJsClass(type: IrType) =
|
||||
private fun callGetClassByType(type: IrType) =
|
||||
JsIrBuilder.buildCall(
|
||||
context.intrinsics.jsClass,
|
||||
reflectionSymbols.getClassData,
|
||||
typeArguments = listOf(type),
|
||||
origin = JsLoweredDeclarationOrigin.CLASS_REFERENCE
|
||||
)
|
||||
@@ -157,7 +162,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
}
|
||||
|
||||
private fun createDynamicType(): IrExpression {
|
||||
return buildCall(context.intrinsics.createDynamicKType!!)
|
||||
return buildCall(reflectionSymbols.createDynamicKType!!)
|
||||
}
|
||||
|
||||
private fun createSimpleKType(type: IrSimpleType, visitedTypeParams: MutableSet<IrTypeParameter>): IrExpression {
|
||||
@@ -169,15 +174,16 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
// }
|
||||
|
||||
val kClassifier = createKClassifier(classifier, visitedTypeParams)
|
||||
// TODO: Use static array types
|
||||
val arguments = type.arguments.map { createKTypeProjection(it, visitedTypeParams) }.toJsArrayLiteral(
|
||||
context,
|
||||
context.dynamicType,
|
||||
context.dynamicType
|
||||
val arguments = context.createArrayOfExpression(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
arrayElementType = context.reflectionSymbols.kTypeClass.defaultType,
|
||||
arrayElements = type.arguments.map { createKTypeProjection(it, visitedTypeParams) }
|
||||
)
|
||||
|
||||
val isMarkedNullable = JsIrBuilder.buildBoolean(context.irBuiltIns.booleanType, type.isMarkedNullable())
|
||||
return buildCall(
|
||||
context.intrinsics.createKType!!,
|
||||
reflectionSymbols.createKType!!,
|
||||
kClassifier,
|
||||
arguments,
|
||||
isMarkedNullable
|
||||
@@ -186,13 +192,13 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
|
||||
private fun createKTypeProjection(tp: IrTypeArgument, visitedTypeParams: MutableSet<IrTypeParameter>): IrExpression {
|
||||
if (tp !is IrTypeProjection) {
|
||||
return buildCall(context.intrinsics.getStarKTypeProjection!!)
|
||||
return buildCall(reflectionSymbols.getStarKTypeProjection!!)
|
||||
}
|
||||
|
||||
val factoryName = when (tp.variance) {
|
||||
Variance.INVARIANT -> context.intrinsics.createInvariantKTypeProjection!!
|
||||
Variance.IN_VARIANCE -> context.intrinsics.createContravariantKTypeProjection!!
|
||||
Variance.OUT_VARIANCE -> context.intrinsics.createCovariantKTypeProjection!!
|
||||
Variance.INVARIANT -> reflectionSymbols.createInvariantKTypeProjection!!
|
||||
Variance.IN_VARIANCE -> reflectionSymbols.createContravariantKTypeProjection!!
|
||||
Variance.OUT_VARIANCE -> reflectionSymbols.createCovariantKTypeProjection!!
|
||||
}
|
||||
|
||||
val kType = createKType(tp.type, visitedTypeParams)
|
||||
@@ -213,10 +219,12 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
visitedTypeParams.add(typeParameter)
|
||||
|
||||
val name = JsIrBuilder.buildString(context.irBuiltIns.stringType, typeParameter.name.asString())
|
||||
val upperBounds = typeParameter.superTypes.map { createKType(it, visitedTypeParams) }.toJsArrayLiteral(
|
||||
context,
|
||||
context.dynamicType,
|
||||
context.dynamicType
|
||||
|
||||
val upperBounds = context.createArrayOfExpression(
|
||||
startOffset = UNDEFINED_OFFSET,
|
||||
endOffset = UNDEFINED_OFFSET,
|
||||
arrayElementType = context.reflectionSymbols.kTypeClass.defaultType,
|
||||
arrayElements = typeParameter.superTypes.map { createKType(it, visitedTypeParams) }
|
||||
)
|
||||
|
||||
val variance = when (typeParameter.variance) {
|
||||
@@ -231,7 +239,7 @@ class ClassReferenceLowering(val context: JsCommonBackendContext) : BodyLowering
|
||||
// }
|
||||
|
||||
return buildCall(
|
||||
context.intrinsics.createKTypeParameter!!,
|
||||
reflectionSymbols.createKTypeParameter!!,
|
||||
name,
|
||||
upperBounds,
|
||||
variance
|
||||
|
||||
-3
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.ir.backend.js.transformers.irToJs
|
||||
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.*
|
||||
import org.jetbrains.kotlin.ir.backend.js.utils.getClassRef
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
@@ -15,11 +14,9 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.getInlineClassBackingField
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.js.backend.ast.*
|
||||
import java.lang.IllegalArgumentException
|
||||
|
||||
typealias IrCallTransformer = (IrCall, context: JsGenerationContext) -> JsExpression
|
||||
|
||||
|
||||
@@ -71,19 +71,6 @@ fun IrDeclaration.hasStaticDispatch() = when (this) {
|
||||
else -> true
|
||||
}
|
||||
|
||||
fun List<IrExpression>.toJsArrayLiteral(context: JsCommonBackendContext, arrayType: IrType, elementType: IrType): IrExpression {
|
||||
val irVararg = IrVarargImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType, elementType, this)
|
||||
|
||||
return IrCallImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, arrayType,
|
||||
context.intrinsics.arrayLiteral,
|
||||
valueArgumentsCount = 1,
|
||||
typeArgumentsCount = 0
|
||||
).apply {
|
||||
putValueArgument(0, irVararg)
|
||||
}
|
||||
}
|
||||
|
||||
val IrValueDeclaration.isDispatchReceiver: Boolean
|
||||
get() {
|
||||
val parent = this.parent
|
||||
|
||||
Reference in New Issue
Block a user