Implement better workflow of interpretation with callable reference
This commit is contained in:
committed by
TeamCityServer
parent
9a8e0f3fb3
commit
e0438d1123
+52
-5
@@ -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<IdSignature, IrBody> = interpreter.bodyMap
|
||||
|
||||
override fun interceptProxy(irFunction: IrFunction, valueArguments: List<Variable>, 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<State>, 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<State>) {
|
||||
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<State>, 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)))
|
||||
}
|
||||
}
|
||||
|
||||
+10
-7
@@ -192,8 +192,8 @@ private fun unfoldStatements(statements: List<IrStatement>, 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) {
|
||||
|
||||
+15
-11
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
+55
-3
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+26
-2
@@ -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<KParameter, Any?>): 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<KParameter, Any?>) {
|
||||
|
||||
+1
-7
@@ -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<T>(val value: T, val type: IrType) : State {
|
||||
override val fields: MutableList<Variable> = 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
|
||||
|
||||
+3
-6
@@ -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("<anonymous>") || it == Name.special("<no name provided>") }
|
||||
|
||||
+6
-9
@@ -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<KParameter>? = 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
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user