From 0e7520fde3ab0295163dae3ae15295ddc12859d5 Mon Sep 17 00:00:00 2001 From: Roman Artemev Date: Wed, 31 Oct 2018 18:30:37 +0300 Subject: [PATCH] [JS IR BE] Fix GetClass on primitive type --- .../ir/backend/js/JsIrBackendContext.kt | 6 ++++ .../js/lower/ClassReferenceLowering.kt | 35 +++++++++++++++---- .../box/classLiteral/bound/primitives.kt | 2 -- 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt index d87ccc6ed00..79436f05738 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsIrBackendContext.kt @@ -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() + 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()) { m, t -> diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt index 37addfdbe81..943c4905357 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ClassReferenceLowering.kt @@ -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 ) }) } diff --git a/compiler/testData/codegen/box/classLiteral/bound/primitives.kt b/compiler/testData/codegen/box/classLiteral/bound/primitives.kt index b15c5b21169..c2fd3c472e9 100644 --- a/compiler/testData/codegen/box/classLiteral/bound/primitives.kt +++ b/compiler/testData/codegen/box/classLiteral/bound/primitives.kt @@ -1,5 +1,3 @@ -// IGNORE_BACKEND: JS_IR - // WITH_RUNTIME import kotlin.test.assertEquals