[JS IR BE] Fix KProperty access in case of both receivers

This commit is contained in:
Roman Artemev
2019-05-13 19:35:23 +03:00
committed by romanart
parent cd3fd60dd7
commit 600ad7e088
2 changed files with 25 additions and 8 deletions
@@ -6,11 +6,10 @@
package org.jetbrains.kotlin.ir.backend.js.lower.calls
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.util.irCall
import org.jetbrains.kotlin.ir.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrDynamicMemberExpressionImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrDynamicOperatorExpressionImpl
import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
import org.jetbrains.kotlin.name.Name
@@ -18,6 +17,17 @@ import org.jetbrains.kotlin.name.Name
class ReflectionCallsTransformer(private val context: JsIrBackendContext) : CallsTransformer {
private val nameToTransformer: Map<Name, (IrFunctionAccessExpression) -> IrExpression>
private fun buildDynamicCall(name: String, call: IrFunctionAccessExpression): IrExpression {
val reference = IrDynamicMemberExpressionImpl(call.startOffset, call.endOffset, context.dynamicType, name, call.dispatchReceiver!!)
return IrDynamicOperatorExpressionImpl(call.startOffset, call.endOffset, call.type, IrDynamicOperator.INVOKE).apply {
receiver = reference
for (i in 0 until call.valueArgumentsCount) {
arguments += call.getValueArgument(i)!!
}
}
}
init {
nameToTransformer = mutableMapOf()
nameToTransformer.run {
@@ -26,14 +36,22 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
{ call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kCallableClass) } ?: false
},
{ call -> irCall(call, context.intrinsics.jsName, dispatchReceiverAsFirstArgument = true) })
{ call ->
IrDynamicMemberExpressionImpl(
call.startOffset,
call.endOffset,
context.irBuiltIns.stringType,
Namer.KCALLABLE_NAME,
call.dispatchReceiver!!
)
})
addWithPredicate(
Name.identifier(Namer.KPROPERTY_GET),
{ call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false
},
{ call -> irCall(call, context.intrinsics.jsPropertyGet, dispatchReceiverAsFirstArgument = true) }
{ call -> buildDynamicCall(Namer.KPROPERTY_GET, call) }
)
addWithPredicate(
@@ -41,7 +59,7 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
{ call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false
},
{ call -> irCall(call, context.intrinsics.jsPropertySet, dispatchReceiverAsFirstArgument = true) }
{ call -> buildDynamicCall(Namer.KPROPERTY_SET, call) }
)
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// WITH_REFLECT
// KJS_WITH_FULL_RUNTIME