diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt index 339e7aa67a3..f1134a61bcd 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/CallInterceptor.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.interpreter.builtins.evaluateIntrinsicAnnotation import org.jetbrains.kotlin.ir.interpreter.builtins.interpretBinaryFunction @@ -23,6 +24,8 @@ import org.jetbrains.kotlin.ir.interpreter.state.* import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState +import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol +import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.impl.originalKotlinType import org.jetbrains.kotlin.ir.util.* @@ -51,19 +54,19 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : private val bodyMap: Map = interpreter.bodyMap override fun interceptProxy(irFunction: IrFunction, valueArguments: List, expectedResultClass: Class<*>): Any? { - return interpreter.withNewCallStack(irFunction) { - this@withNewCallStack.environment.callStack.addInstruction(CompoundInstruction(irFunction)) + val irCall = IrCallImpl.fromSymbolOwner(0, 0, irFunction.returnType, irFunction.symbol as IrSimpleFunctionSymbol) + return interpreter.withNewCallStack(irCall) { + this@withNewCallStack.environment.callStack.addInstruction(SimpleInstruction(irCall)) valueArguments.forEach { this@withNewCallStack.environment.callStack.addVariable(it) } }.wrap(this@DefaultCallInterceptor, remainArraysAsIs = true, extendFrom = expectedResultClass) } override fun interceptCall(call: IrCall, irFunction: IrFunction, receiver: State?, args: List, defaultAction: () -> Unit) { val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly")) - val originalCallName = call.symbol.owner.name.asString() when { receiver is Wrapper && !isInlineOnly -> receiver.getMethod(irFunction).invokeMethod(irFunction, args) irFunction.hasAnnotation(evaluateIntrinsicAnnotation) -> Wrapper.getStaticMethod(irFunction).invokeMethod(irFunction, args) - receiver is KFunctionState && originalCallName == "invoke" -> callStack.addInstruction(CompoundInstruction(irFunction)) + receiver is KFunctionState && call.symbol.owner.name.asString() == "invoke" -> handleInvoke(call, receiver, args) receiver is ReflectionState -> Wrapper.getReflectionMethod(irFunction).invokeMethod(irFunction, args) receiver is Primitive<*> -> calculateBuiltIns(irFunction, args) // check for js char, js long and get field for primitives irFunction.body is IrSyntheticBody -> handleIntrinsicMethods(irFunction) @@ -73,6 +76,50 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : } } + // TODO unite this logic with interpretCall + private fun handleInvoke(call: IrCall, functionState: KFunctionState, args: List) { + val invokedFunction = functionState.irFunction + + var index = 1 // drop first arg that is reference to function + val dispatchReceiver = invokedFunction.dispatchReceiverParameter?.let { functionState.getState(it.symbol) ?: args[index++] } + val extensionReceiver = invokedFunction.extensionReceiverParameter?.let { functionState.getState(it.symbol) ?: args[index++] } + val valueArguments = invokedFunction.valueParameters.map { args[index++] } + + val function = when (val symbol = invokedFunction.symbol) { + is IrSimpleFunctionSymbol -> { + val irCall = IrCallImpl.fromSymbolOwner(0, 0, invokedFunction.returnType, invokedFunction.symbol as IrSimpleFunctionSymbol) + val actualFunction = dispatchReceiver?.getIrFunctionByIrCall(irCall) ?: invokedFunction + callStack.newFrame(actualFunction, listOf(SimpleInstruction(actualFunction))) + callStack.addVariable(Variable(actualFunction.symbol, KTypeState(call.type, irBuiltIns.anyClass.owner))) + + actualFunction + } + is IrConstructorSymbol -> { + val irConstructorCall = IrConstructorCallImpl.fromSymbolOwner(invokedFunction.returnType, symbol) + callStack.newSubFrame(irConstructorCall, listOf(SimpleInstruction(irConstructorCall))) + callStack.addVariable(Variable(invokedFunction.parentAsClass.thisReceiver!!.symbol, Common(invokedFunction.parentAsClass))) + + invokedFunction + } + else -> TODO("unsupported symbol $symbol for invoke") + } + + function.dispatchReceiverParameter?.let { callStack.addVariable(Variable(it.symbol, dispatchReceiver!!)) } + function.extensionReceiverParameter?.let { callStack.addVariable(Variable(it.symbol, extensionReceiver!!)) } + function.valueParameters.forEachIndexed { i, param -> callStack.addVariable(Variable(param.symbol, valueArguments[i])) } + + callStack.loadUpValues(functionState) + if (extensionReceiver is StateWithClosure) callStack.loadUpValues(extensionReceiver) + if (dispatchReceiver is Complex && function.parentClassOrNull?.isInner == true) { + generateSequence(dispatchReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { callStack.addVariable(it) } + } + + if (invokedFunction.symbol is IrConstructorSymbol) return + this.interceptCall(call, function, dispatchReceiver, listOfNotNull(dispatchReceiver, extensionReceiver) + valueArguments) { + callStack.addInstruction(CompoundInstruction(function)) + } + } + override fun interceptConstructor( constructorCall: IrFunctionAccessExpression, receiver: State, args: List, defaultAction: () -> Unit ) { @@ -133,7 +180,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : this ?: return handleIntrinsicMethods(irFunction) val argsForMethodInvocation = irFunction.getArgsForMethodInvocation(this@DefaultCallInterceptor, this.type(), args) withExceptionHandler(environment) { - val result = this.invokeWithArguments(argsForMethodInvocation) + val result = this.invokeWithArguments(argsForMethodInvocation) // TODO if null return Unit callStack.pushState(result.toState(result.getType(irFunction.returnType))) } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt index 2594e35ad72..9437d25d67a 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/InstructionsUnfolder.kt @@ -192,8 +192,8 @@ private fun unfoldStatements(statements: List, callStack: CallStack } private fun unfoldReturn(expression: IrReturn, callStack: CallStack) { - callStack.addInstruction(SimpleInstruction(expression)) //2 - callStack.addInstruction(CompoundInstruction(expression.value)) //1 + callStack.addInstruction(SimpleInstruction(expression)) + callStack.addInstruction(CompoundInstruction(expression.value)) } private fun unfoldSetField(expression: IrSetField, callStack: CallStack) { @@ -375,11 +375,14 @@ private fun unfoldFunctionReference(reference: IrFunctionReference, callStack: C } private fun unfoldPropertyReference(propertyReference: IrPropertyReference, callStack: CallStack) { - callStack.addInstruction(SimpleInstruction(propertyReference)) - propertyReference.dispatchReceiver?.let { - callStack.addInstruction(SimpleInstruction(propertyReference.getter!!.owner.dispatchReceiverParameter!!)) - callStack.addInstruction(CompoundInstruction(it)) - } + val getter = propertyReference.getter!!.owner + callStack.newSubFrame(propertyReference, listOf(SimpleInstruction(propertyReference))) + + propertyReference.dispatchReceiver?.let { callStack.addInstruction(SimpleInstruction(getter.dispatchReceiverParameter!!)) } + propertyReference.extensionReceiver?.let { callStack.addInstruction(SimpleInstruction(getter.extensionReceiverParameter!!)) } + + propertyReference.extensionReceiver?.let { callStack.addInstruction(CompoundInstruction(it)) } + propertyReference.dispatchReceiver?.let { callStack.addInstruction(CompoundInstruction(it)) } } private fun unfoldClassReference(classReference: IrClassReference, callStack: CallStack) { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index 48349659811..4e39fe9f44f 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -79,9 +79,10 @@ class IrInterpreter private constructor( return callStack.popState().toIrExpression(expression).apply { callStack.dropFrame() } } - internal fun withNewCallStack(frameOwner: IrFunction, init: IrInterpreter.() -> Any?): State { + internal fun withNewCallStack(call: IrCall, init: IrInterpreter.() -> Any?): State { return with(IrInterpreter(environment.copyWithNewCallStack(), bodyMap)) { - callStack.newFrame(frameOwner, listOf()) + callStack.newFrame(call.symbol.owner, listOf()) + callStack.newSubFrame(call, listOf()) init() while (!callStack.hasNoInstructions()) { @@ -168,8 +169,8 @@ class IrInterpreter private constructor( private fun interpretCall(call: IrCall) { val owner = call.symbol.owner // 1. load evaluated arguments from stack - var dispatchReceiver = call.dispatchReceiver?.let { callStack.getVariable(owner.getDispatchReceiver()!!) }?.state - val extensionReceiver = call.extensionReceiver?.let { callStack.getVariable(owner.getExtensionReceiver()!!) }?.state + var dispatchReceiver = owner.getDispatchReceiver()?.let { callStack.getVariable(it) }?.state + val extensionReceiver = owner.getExtensionReceiver()?.let { callStack.getVariable(it) }?.state val valueArguments = owner.valueParameters.map { callStack.getVariable(it.symbol).state } // 2. get correct function for interpretation @@ -208,7 +209,7 @@ class IrInterpreter private constructor( generateSequence(dispatchReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { callStack.addVariable(it) } } - callInterceptor.interceptCall(call, irFunction, dispatchReceiver, args.map { it.state }) { + callInterceptor.interceptCall(call, irFunction, dispatchReceiver, listOfNotNull(dispatchReceiver, extensionReceiver) + valueArguments) { callStack.addInstruction(CompoundInstruction(irFunction)) } } @@ -241,8 +242,8 @@ class IrInterpreter private constructor( } private fun interpretConstructorCall(constructorCall: IrFunctionAccessExpression) { - val valueArguments = constructorCall.symbol.owner.valueParameters.map { callStack.getVariable(it.symbol).state } val constructor = constructorCall.symbol.owner + val valueArguments = constructor.valueParameters.map { callStack.getVariable(it.symbol).state } val irClass = constructor.parentAsClass val objectVar = callStack.getVariable(constructorCall.getThisReceiver()) if (irClass.isLocal) callStack.storeUpValues(objectVar.state as StateWithClosure) @@ -367,7 +368,7 @@ class IrInterpreter private constructor( callStack.addInstruction(CompoundInstruction(field.initializer?.expression)) } // receiver is null, for example, for top level fields - expression.receiver.let { it == null || (it.type.classifierOrNull?.owner as? IrClass)?.isObject == true } -> { + expression.receiver == null -> { val propertyOwner = field.correspondingPropertySymbol?.owner val isConst = propertyOwner?.isConst == true || propertyOwner?.backingField?.initializer?.expression is IrConst<*> assert(isConst) { "Cannot interpret get method on top level non const properties" } @@ -576,10 +577,13 @@ class IrInterpreter private constructor( } private fun interpretPropertyReference(propertyReference: IrPropertyReference) { - val dispatchReceiverSymbol = propertyReference.getter?.owner?.getDispatchReceiver() - val dispatchReceiver = propertyReference.dispatchReceiver?.let { callStack.getVariable(dispatchReceiverSymbol!!) }?.state - // it is impossible to get KProperty2 through ::, so extension receiver is always null - val propertyState = KPropertyState(propertyReference, dispatchReceiver) + val receiverSymbol = propertyReference.getter?.owner?.let { it.getDispatchReceiver() ?: it.getExtensionReceiver() } + // it is impossible to get KProperty2 through ::, so only one receiver can be not null (or both null) + val receiver = (propertyReference.dispatchReceiver ?: propertyReference.extensionReceiver) + ?.let { callStack.getVariable(receiverSymbol!!) }?.state + + callStack.dropSubFrame() + val propertyState = KPropertyState(propertyReference, receiver) callStack.pushState(propertyState) } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt index 03893236744..c1575fadac0 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt @@ -7,12 +7,19 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection import org.jetbrains.kotlin.builtins.functions.BuiltInFunctionArity import org.jetbrains.kotlin.descriptors.Modality +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression +import org.jetbrains.kotlin.ir.expressions.IrReturn +import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall import org.jetbrains.kotlin.ir.interpreter.CallInterceptor import org.jetbrains.kotlin.ir.interpreter.stack.Variable import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState import org.jetbrains.kotlin.ir.interpreter.toState +import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.util.isSuspend +import org.jetbrains.kotlin.ir.util.statements import kotlin.reflect.* internal class KFunctionProxy( @@ -68,17 +75,62 @@ internal class KFunctionProxy( override fun equals(other: Any?): Boolean { if (this === other) return true - if (other !is ReflectionProxy) return false + if (other !is KFunctionProxy) return false + if (arity != other.arity || isSuspend != other.isSuspend) return false + if (state.fields.zip(other.state.fields).any { (first, second) -> first.state !== second.state }) return false - return state == other.state + return when { + state.irFunction.isAdapter() && other.state.irFunction.isAdapter() -> state.irFunction.eqaulsByAdapteeCall(other.state.irFunction) + else -> state.irFunction == other.state.irFunction + } } override fun hashCode(): Int { - return state.hashCode() + return when { + state.irFunction.isAdapter() -> state.irFunction.getAdapteeCallSymbol()!!.hashCode() + else -> state.irFunction.hashCode() + } } override fun toString(): String { return state.toString() } + + private fun IrFunction.isAdapter() = this.origin == IrDeclarationOrigin.ADAPTER_FOR_CALLABLE_REFERENCE + + private fun IrFunction.getAdapteeCallSymbol(): IrFunctionSymbol? { + if (!this.isAdapter()) return null + + val call = when (val statement = this.body!!.statements.single()) { + is IrTypeOperatorCall -> statement.argument + is IrReturn -> statement.value + else -> statement + } + return (call as? IrFunctionAccessExpression)?.symbol + } + + private fun IrFunction.eqaulsByAdapteeCall(other: IrFunction): Boolean { + if (!this.isAdapter() || !other.isAdapter()) return false + + val statement = this.body!!.statements.single() + val otherStatement = other.body!!.statements.single() + + val (thisArg, otherArg) = when (statement) { + is IrTypeOperatorCall -> { + if (otherStatement !is IrTypeOperatorCall) return false + Pair(statement.argument, otherStatement.argument) + } + is IrReturn -> { + if (otherStatement !is IrReturn) return false + Pair(statement.value, otherStatement.value) + } + else -> Pair(statement, otherStatement) + } + + if (thisArg !is IrFunctionAccessExpression || otherArg !is IrFunctionAccessExpression) return false + if (thisArg.symbol != otherArg.symbol) return false + + return true + } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt index 7c1c9e7e130..4558a3a8e8e 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KProperty0Proxy.kt @@ -6,7 +6,10 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection import org.jetbrains.kotlin.ir.interpreter.CallInterceptor +import org.jetbrains.kotlin.ir.interpreter.getDispatchReceiver +import org.jetbrains.kotlin.ir.interpreter.getExtensionReceiver import org.jetbrains.kotlin.ir.interpreter.stack.Variable +import org.jetbrains.kotlin.ir.interpreter.state.isNull import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState import org.jetbrains.kotlin.ir.interpreter.toState import org.jetbrains.kotlin.ir.util.resolveFakeOverride @@ -22,7 +25,19 @@ internal open class KProperty0Proxy( override fun call(vararg args: Any?): Any? { checkArguments(0, args.size) val actualPropertySymbol = state.property.resolveFakeOverride()?.symbol ?: state.property.symbol - return state.dispatchReceiver!!.getState(actualPropertySymbol)!! + val receiver = state.receiver // null receiver <=> property is on top level + ?: return callInterceptor.interceptProxy(getter, emptyList()) + + val value = receiver.getState(actualPropertySymbol) + return when { + // null value <=> property is extension or Primitive; receiver.isNull() <=> nullable extension + value == null || receiver.isNull() -> { + val receiverSymbol = getter.getDispatchReceiver() ?: getter.getExtensionReceiver() + val receiverVariable = receiverSymbol?.let { Variable(it, receiver) } + callInterceptor.interceptProxy(getter, listOfNotNull(receiverVariable)) + } + else -> value + } } override fun callBy(args: Map): Any? { @@ -48,7 +63,16 @@ internal class KMutableProperty0Proxy( override fun call(vararg args: Any?) { checkArguments(1, args.size) - state.dispatchReceiver!!.setField(Variable(state.property.symbol, args.single().toState(propertyType))) + // null receiver <=> property is on top level + assert(state.receiver != null) { "Cannot interpret set method on top level non const properties" } + val receiver = state.receiver!! + val newValue = args.single().toState(propertyType) + setter.getExtensionReceiver() + ?.let { + val fieldSymbol = setter.valueParameters.single().symbol + callInterceptor.interceptProxy(setter, listOf(Variable(it, receiver), Variable(fieldSymbol, newValue))) + } + ?: receiver.setField(Variable(state.property.symbol, newValue)) } override fun callBy(args: Map) { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt index d828927c4e9..9581bbff7b5 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt @@ -7,8 +7,6 @@ package org.jetbrains.kotlin.ir.interpreter.state import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.declarations.IrProperty -import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.interpreter.getLastOverridden import org.jetbrains.kotlin.ir.interpreter.stack.Variable @@ -16,16 +14,12 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.util.defaultType -import org.jetbrains.kotlin.ir.util.isFakeOverride -import org.jetbrains.kotlin.ir.util.overrides internal class Primitive(val value: T, val type: IrType) : State { override val fields: MutableList = mutableListOf() override val irClass: IrClass = type.classOrNull!!.owner - override fun getState(symbol: IrSymbol): State { - return super.getState(symbol) ?: this - } + override fun getState(symbol: IrSymbol): State? = null override fun getIrFunctionByIrCall(expression: IrCall): IrFunction { val owner = expression.symbol.owner diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt index 930745b14e3..b7b0778b21a 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt @@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory -import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrFunctionReference import org.jetbrains.kotlin.ir.interpreter.CallInterceptor import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KParameterProxy @@ -61,11 +60,9 @@ internal class KFunctionState(val irFunction: IrFunction, override val irClass: } fun getArity(): Int? { - return irClass.name.asString().removePrefix("Function").removePrefix("KFunction").toIntOrNull() - } - - override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? { - return if (expression.symbol.owner.name.asString() == "invoke") irFunction else null + return irClass.name.asString() + .removePrefix("Suspend").removePrefix("Function").removePrefix("KFunction") + .toIntOrNull() } private fun isLambda(): Boolean = irFunction.name.let { it == Name.special("") || it == Name.special("") } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt index 5eabfbfe9c1..abf1836f10a 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt @@ -16,12 +16,9 @@ import org.jetbrains.kotlin.ir.types.classOrNull import kotlin.reflect.KParameter import kotlin.reflect.KType -internal class KPropertyState( - val property: IrProperty, override val irClass: IrClass, val dispatchReceiver: State? = null -) : ReflectionState() { - - constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?) - : this(propertyReference.symbol.owner, propertyReference.type.classOrNull!!.owner, dispatchReceiver) +internal class KPropertyState(val property: IrProperty, override val irClass: IrClass, val receiver: State? = null) : ReflectionState() { + constructor(propertyReference: IrPropertyReference, receiver: State?) + : this(propertyReference.symbol.owner, propertyReference.type.classOrNull!!.owner, receiver) private var _parameters: List? = null private var _returnType: KType? = null @@ -30,7 +27,7 @@ internal class KPropertyState( if (_parameters != null) return _parameters!! val kParameterIrClass = irClass.getIrClassOfReflectionFromList("parameters") var index = 0 - val instanceParameter = property.getter?.dispatchReceiverParameter?.takeIf { dispatchReceiver == null } + val instanceParameter = property.getter?.dispatchReceiverParameter?.takeIf { receiver == null } ?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.INSTANCE), callInterceptor) } val extensionParameter = property.getter?.extensionReceiverParameter ?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.EXTENSION_RECEIVER), callInterceptor) } @@ -64,14 +61,14 @@ internal class KPropertyState( other as KPropertyState if (property != other.property) return false - if (dispatchReceiver != other.dispatchReceiver) return false + if (receiver != other.receiver) return false return true } override fun hashCode(): Int { var result = property.hashCode() - result = 31 * result + (dispatchReceiver?.hashCode() ?: 0) + result = 31 * result + (receiver?.hashCode() ?: 0) return result }