[JS IR BE] Fix GetClass on primitive type

This commit is contained in:
Roman Artemev
2018-10-31 18:30:37 +03:00
committed by romanart
parent 2d03f87ea5
commit 0e7520fde3
3 changed files with 35 additions and 8 deletions
@@ -227,6 +227,12 @@ class JsIrBackendContext(
val coroutineImplExceptionProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exception")!! }
val coroutineImplExceptionStateProperty by lazy { ir.symbols.coroutineImpl.getPropertyDeclaration("exceptionState")!! }
val primitiveClassesObject = symbolTable.referenceClass(
getClass(FqName.fromSegments(listOf("kotlin", "reflect", "js", "internal", "PrimitiveClasses")))
).owner
val primitiveClassProperties = primitiveClassesObject.declarations.filterIsInstance<IrProperty>()
private fun referenceOperators() = OperatorNames.ALL.map { name ->
// TODO to replace KotlinType with IrType we need right equals on IrType
name to irBuiltIns.primitiveTypes.fold(mutableMapOf<KotlinType, IrFunctionSymbol>()) { m, t ->
@@ -9,26 +9,50 @@ import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrClassReference
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetClass
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name
class ClassReferenceLowering(val context: JsIrBackendContext) : FileLoweringPass {
private val intrinsics = context.intrinsics
private val primitiveClassesObject = context.primitiveClassesObject
private val primitiveClassProperties = context.primitiveClassProperties
private val booleanClass = primitiveClassProperties.single { it.name == Name.identifier("booleanClass") }
private val intClass = primitiveClassProperties.single { it.name == Name.identifier("intClass") }
private val doubleClass = primitiveClassProperties.single { it.name == Name.identifier("doubleClass") }
private fun callGetKClassFromExpression(returnType: IrType, typeArgument: IrType, argument: IrExpression) =
JsIrBuilder.buildCall(intrinsics.jsGetKClassFromExpression, returnType, listOf(typeArgument)).apply {
putValueArgument(0, argument)
}
private fun callGetKClass(returnType: IrType, typeArgument: IrType, argument: IrExpression) =
JsIrBuilder.buildCall(intrinsics.jsGetKClass, 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.symbol)
}
private fun callGetKClass(returnType: IrType, typeArgument: IrType) = when {
typeArgument.isBoolean() -> getPrimitiveClass(booleanClass.getter!!, returnType)
typeArgument.isByte() -> getPrimitiveClass(intClass.getter!!, returnType)
typeArgument.isShort() -> getPrimitiveClass(intClass.getter!!, returnType)
typeArgument.isInt() -> getPrimitiveClass(intClass.getter!!, returnType)
typeArgument.isFloat() -> getPrimitiveClass(doubleClass.getter!!, returnType)
typeArgument.isDouble() -> getPrimitiveClass(doubleClass.getter!!, returnType)
else -> JsIrBuilder.buildCall(intrinsics.jsGetKClass, returnType, listOf(typeArgument)).apply {
putValueArgument(0, callJsClass(typeArgument))
}
}
private fun callJsClass(type: IrType) =
JsIrBuilder.buildCall(intrinsics.jsClass, typeArguments = listOf(type))
@@ -44,8 +68,7 @@ class ClassReferenceLowering(val context: JsIrBackendContext) : FileLoweringPass
override fun visitClassReference(expression: IrClassReference) =
callGetKClass(
returnType = expression.type,
typeArgument = expression.classType,
argument = callJsClass(expression.classType)
typeArgument = expression.classType
)
})
}
@@ -1,5 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_RUNTIME
import kotlin.test.assertEquals