[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 package org.jetbrains.kotlin.ir.backend.js.lower.calls
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext 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.backend.js.utils.Namer
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.impl.IrDynamicMemberExpressionImpl
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression import org.jetbrains.kotlin.ir.expressions.impl.IrDynamicOperatorExpressionImpl
import org.jetbrains.kotlin.ir.types.isSubtypeOfClass import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -18,6 +17,17 @@ import org.jetbrains.kotlin.name.Name
class ReflectionCallsTransformer(private val context: JsIrBackendContext) : CallsTransformer { class ReflectionCallsTransformer(private val context: JsIrBackendContext) : CallsTransformer {
private val nameToTransformer: Map<Name, (IrFunctionAccessExpression) -> IrExpression> 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 { init {
nameToTransformer = mutableMapOf() nameToTransformer = mutableMapOf()
nameToTransformer.run { nameToTransformer.run {
@@ -26,14 +36,22 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
{ call -> { call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kCallableClass) } ?: false 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( addWithPredicate(
Name.identifier(Namer.KPROPERTY_GET), Name.identifier(Namer.KPROPERTY_GET),
{ call -> { call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false 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( addWithPredicate(
@@ -41,7 +59,7 @@ class ReflectionCallsTransformer(private val context: JsIrBackendContext) : Call
{ call -> { call ->
call.symbol.owner.dispatchReceiverParameter?.run { type.isSubtypeOfClass(context.irBuiltIns.kPropertyClass) } ?: false 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 // WITH_REFLECT
// KJS_WITH_FULL_RUNTIME // KJS_WITH_FULL_RUNTIME