Implement correct processing for receivers of IrFunctionReference

This commit is contained in:
Ivan Kylchik
2021-03-11 02:04:09 +03:00
committed by TeamCityServer
parent a73173e480
commit c3ad319c13
2 changed files with 21 additions and 4 deletions
@@ -231,7 +231,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
expression: IrFunctionAccessExpression, irFunction: IrFunction, pool: MutableList<Variable>
): ExecutionResult {
// if irFunction is lambda and it has receiver, then first descriptor must be taken from extension receiver
val receiverAsFirstArgument = when (expression.dispatchReceiver?.type?.isFunction()) {
val receiverAsFirstArgument = when (expression.valueArgumentsCount != irFunction.valueParameters.size) {
true -> listOfNotNull(irFunction.getExtensionReceiver())
else -> listOf()
}
@@ -861,7 +861,23 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
}
private fun interpretFunctionReference(reference: IrFunctionReference): ExecutionResult {
stack.pushReturnValue(KFunctionState(reference))
val function = KFunctionState(reference)
// dispatch receiver processing
val rawDispatchReceiver = reference.dispatchReceiver
rawDispatchReceiver?.interpret()?.check { return it }
val dispatchReceiver = rawDispatchReceiver?.let { stack.popReturnValue() }?.checkNullability(rawDispatchReceiver.type)
// extension receiver processing
val rawExtensionReceiver = reference.extensionReceiver
rawExtensionReceiver?.interpret()?.check { return it }
val extensionReceiver = rawExtensionReceiver?.let { stack.popReturnValue() }?.checkNullability(rawExtensionReceiver.type)
function.irFunction.getDispatchReceiver()?.let { dispatchReceiver?.let { receiver -> function.fields.add(Variable(it, receiver)) } }
function.irFunction.getExtensionReceiver()?.let { extensionReceiver?.let { receiver -> function.fields.add(Variable(it, receiver)) } }
if (function.irFunction.isLocal) function.fields.addAll(stack.getAll()) // TODO save only necessary declarations
stack.pushReturnValue(function)
return Next
}
@@ -8,8 +8,8 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
import org.jetbrains.kotlin.ir.interpreter.state.State
import org.jetbrains.kotlin.ir.interpreter.toState
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
import kotlin.reflect.*
internal open class KProperty0Proxy(
@@ -21,7 +21,8 @@ internal open class KProperty0Proxy(
override fun call(vararg args: Any?): Any? {
checkArguments(0, args.size)
return state.dispatchReceiver!!.getState(state.property.symbol)!!
val actualPropertySymbol = state.property.resolveFakeOverride()?.symbol ?: state.property.symbol
return state.dispatchReceiver!!.getState(actualPropertySymbol)!!
}
override fun callBy(args: Map<KParameter, Any?>): Any? {