Add synthetic function in interpreter for default args evaluation
This commit is contained in:
committed by
TeamCityServer
parent
7852d01da6
commit
10efbeb0c9
+2
-1
@@ -66,9 +66,10 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
|
||||
override fun interceptCall(call: IrCall, irFunction: IrFunction, args: List<State>, defaultAction: () -> Unit) {
|
||||
val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly"))
|
||||
val isSyntheticDefault = irFunction.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER
|
||||
val receiver = if (irFunction.dispatchReceiverParameter != null) args[0] else null
|
||||
when {
|
||||
receiver is Wrapper && !isInlineOnly -> receiver.getMethod(irFunction).invokeMethod(irFunction, args)
|
||||
receiver is Wrapper && !isInlineOnly && !isSyntheticDefault -> receiver.getMethod(irFunction).invokeMethod(irFunction, args)
|
||||
Wrapper.mustBeHandledWithWrapper(irFunction) -> Wrapper.getStaticMethod(irFunction).invokeMethod(irFunction, args)
|
||||
handleIntrinsicMethods(irFunction) -> return
|
||||
receiver.mustBeHandledAsReflection(call) -> Wrapper.getReflectionMethod(irFunction).invokeMethod(irFunction, args)
|
||||
|
||||
+144
-70
@@ -5,24 +5,32 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.InterpreterError
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.verify
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isSubtypeOf
|
||||
import org.jetbrains.kotlin.ir.types.isUnit
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal fun IrExpression.handleAndDropResult(callStack: CallStack, dropOnlyUnit: Boolean = false) {
|
||||
val dropResult = fun() {
|
||||
@@ -38,10 +46,10 @@ internal fun unfoldInstruction(element: IrElement?, environment: IrInterpreterEn
|
||||
null -> return
|
||||
is IrSimpleFunction -> unfoldFunction(element, environment)
|
||||
is IrConstructor -> unfoldConstructor(element, callStack)
|
||||
is IrCall -> unfoldCall(element, callStack)
|
||||
is IrConstructorCall -> unfoldConstructorCall(element, callStack)
|
||||
is IrEnumConstructorCall -> unfoldConstructorCall(element, callStack)
|
||||
is IrDelegatingConstructorCall -> unfoldConstructorCall(element, callStack)
|
||||
is IrCall -> unfoldCall(element, environment)
|
||||
is IrConstructorCall -> unfoldConstructorCall(element, environment)
|
||||
is IrEnumConstructorCall -> unfoldConstructorCall(element, environment)
|
||||
is IrDelegatingConstructorCall -> unfoldConstructorCall(element, environment)
|
||||
is IrInstanceInitializerCall -> unfoldInstanceInitializerCall(element, callStack)
|
||||
is IrField -> unfoldField(element, callStack)
|
||||
is IrBody -> unfoldBody(element, callStack)
|
||||
@@ -109,81 +117,147 @@ private fun unfoldConstructor(constructor: IrConstructor, callStack: CallStack)
|
||||
}
|
||||
}
|
||||
|
||||
private fun unfoldCall(call: IrCall, callStack: CallStack) {
|
||||
unfoldValueParameters(call, callStack)
|
||||
private fun unfoldCall(call: IrCall, environment: IrInterpreterEnvironment) {
|
||||
unfoldValueParameters(call, environment)
|
||||
}
|
||||
|
||||
// This function is responsible for IrConstructorCall, IrDelegatingConstructorCall and IrEnumConstructorCall
|
||||
private fun unfoldConstructorCall(constructorCall: IrFunctionAccessExpression, callStack: CallStack) {
|
||||
unfoldValueParameters(constructorCall, callStack)
|
||||
private fun unfoldConstructorCall(constructorCall: IrFunctionAccessExpression, environment: IrInterpreterEnvironment) {
|
||||
unfoldValueParameters(constructorCall, environment)
|
||||
}
|
||||
|
||||
private fun unfoldValueParameters(expression: IrFunctionAccessExpression, callStack: CallStack) {
|
||||
private fun unfoldValueParameters(expression: IrFunctionAccessExpression, environment: IrInterpreterEnvironment) {
|
||||
val callStack = environment.callStack
|
||||
val irFunction = expression.symbol.owner
|
||||
// new sub frame is used to store value arguments, in case then they are used in default args evaluation
|
||||
callStack.newSubFrame(expression)
|
||||
callStack.addInstruction(SimpleInstruction(expression))
|
||||
|
||||
fun getDefaultForParameterAt(index: Int): IrExpression? {
|
||||
fun IrExpressionBody.replaceGetValueFromOtherClass(): IrExpressionBody {
|
||||
return this.deepCopyWithSymbols(irFunction).transform(
|
||||
object : IrElementTransformerVoid() {
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
val parameter = expression.symbol.owner as? IrValueParameter ?: return super.visitGetValue(expression)
|
||||
if (parameter.parent == irFunction) return super.visitGetValue(expression)
|
||||
val newParameter = when (val indexInParameters = parameter.index) {
|
||||
-1 -> (irFunction.dispatchReceiverParameter ?: irFunction.extensionReceiverParameter)!!
|
||||
else -> irFunction.valueParameters[indexInParameters]
|
||||
val hasDefaults = (0 until expression.valueArgumentsCount).any { expression.getValueArgument(it) == null }
|
||||
if (hasDefaults) {
|
||||
val visibility = if (expression is IrEnumConstructorCall || expression is IrDelegatingConstructorCall) DescriptorVisibilities.LOCAL else irFunction.visibility
|
||||
val defaultFun = IrFunctionImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER,
|
||||
IrSimpleFunctionSymbolImpl(), Name.identifier(irFunction.name.asString() + "\$default"),
|
||||
visibility, Modality.FINAL, irFunction.returnType,
|
||||
isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isOperator = true, isInfix = false, isExpect = false
|
||||
)
|
||||
defaultFun.parent = irFunction.parent
|
||||
expression.dispatchReceiver?.let {
|
||||
defaultFun.dispatchReceiverParameter = irFunction.dispatchReceiverParameter!!//.deepCopyWithSymbols(defaultFun)
|
||||
}
|
||||
expression.extensionReceiver?.let {
|
||||
defaultFun.extensionReceiverParameter = irFunction.extensionReceiverParameter!!//.deepCopyWithSymbols(defaultFun)
|
||||
}
|
||||
val parameters = mutableListOf<IrValueDeclaration>()
|
||||
(0 until expression.valueArgumentsCount).forEach {
|
||||
if (expression.getValueArgument(it) != null) {
|
||||
val param = irFunction.valueParameters[it]//.deepCopyWithSymbols(defaultFun)
|
||||
defaultFun.valueParameters += param
|
||||
parameters += param
|
||||
}
|
||||
}
|
||||
|
||||
val callToDefault = IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, defaultFun.returnType, defaultFun.symbol)
|
||||
expression.dispatchReceiver?.let {
|
||||
callToDefault.dispatchReceiver = it
|
||||
}
|
||||
expression.extensionReceiver?.let {
|
||||
callToDefault.extensionReceiver = it
|
||||
}
|
||||
var index = 0
|
||||
(0 until expression.valueArgumentsCount).forEach {
|
||||
if (expression.getValueArgument(it) != null) {
|
||||
callToDefault.putValueArgument(index++, expression.getValueArgument(it))
|
||||
}
|
||||
}
|
||||
|
||||
fun getDefaultForParameterAt(index: Int): IrExpression? {
|
||||
fun IrExpressionBody.replaceGetValueFromOtherClass(owner: IrFunction): IrExpressionBody {
|
||||
if (this.expression is IrConst<*>) return this
|
||||
return this.deepCopyWithSymbols(owner).transform(
|
||||
object : IrElementTransformerVoid() {
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
val parameter = expression.symbol.owner as? IrValueParameter ?: return super.visitGetValue(expression)
|
||||
if (parameter.parent != owner) return super.visitGetValue(expression)
|
||||
val newParameter = when (val indexInParameters = parameter.index) {
|
||||
-1 -> (irFunction.dispatchReceiverParameter ?: irFunction.extensionReceiverParameter)!!
|
||||
else -> parameters[indexInParameters]//parameters[indexInParameters]
|
||||
}
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, expression.type, newParameter.symbol)
|
||||
}
|
||||
return IrGetValueImpl(expression.startOffset, expression.endOffset, expression.type, newParameter.symbol)
|
||||
}
|
||||
}, null
|
||||
)
|
||||
}
|
||||
|
||||
fun IrValueParameter.getDefault(): IrExpressionBody? {
|
||||
if (defaultValue != null) return defaultValue
|
||||
val overriddenDefault = (this.parent as? IrSimpleFunction)?.overriddenSymbols
|
||||
?.map { it.owner.valueParameters[this.index] }
|
||||
?.firstNotNullOfOrNull { it.getDefault() }
|
||||
|
||||
if (overriddenDefault == null || overriddenDefault.expression is IrConst<*>) return overriddenDefault
|
||||
|
||||
return overriddenDefault.replaceGetValueFromOtherClass()
|
||||
}
|
||||
|
||||
return irFunction.valueParameters[index].getDefault()?.expression
|
||||
}
|
||||
|
||||
val valueParametersSymbols = irFunction.valueParameters.map { it.symbol }
|
||||
|
||||
// evaluate arguments
|
||||
(expression.valueArgumentsCount - 1 downTo 0).forEach { index ->
|
||||
when {
|
||||
expression.getValueArgument(index) != null -> {
|
||||
// interpret arguments that were passed
|
||||
callStack.addInstruction(SimpleInstruction(irFunction.valueParameters[index]))
|
||||
callStack.addInstruction(CompoundInstruction(expression.getValueArgument(index)))
|
||||
}, null
|
||||
)//.deepCopyWithSymbols(defaultFun) TODO ???
|
||||
}
|
||||
else -> {
|
||||
// interpret defaults for null arguments
|
||||
callStack.addInstruction(SimpleInstruction(valueParametersSymbols[index].owner))
|
||||
|
||||
getDefaultForParameterAt(index)
|
||||
?.let { callStack.addInstruction(CompoundInstruction(it)) }
|
||||
?: expression.getVarargType(index)?.let { // case when value parameter is vararg and it is missing
|
||||
callStack.addInstruction(SimpleInstruction(IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it)))
|
||||
}
|
||||
fun IrValueParameter.getDefault(): IrExpressionBody? {
|
||||
if (defaultValue != null) return defaultValue?.replaceGetValueFromOtherClass(this.parent as IrFunction)
|
||||
return (this.parent as? IrSimpleFunction)?.overriddenSymbols
|
||||
?.map { it.owner.valueParameters[this.index] }
|
||||
?.firstOrNull { it.getDefault() != null }?.let { it.getDefault()?.replaceGetValueFromOtherClass(it.parent as IrFunction) }
|
||||
}
|
||||
|
||||
return irFunction.valueParameters[index].getDefault()?.expression
|
||||
}
|
||||
}
|
||||
expression.extensionReceiver?.let {
|
||||
callStack.addInstruction(SimpleInstruction(irFunction.extensionReceiverParameter!!))
|
||||
callStack.addInstruction(CompoundInstruction(it))
|
||||
}
|
||||
expression.dispatchReceiver?.let {
|
||||
callStack.addInstruction(SimpleInstruction(irFunction.dispatchReceiverParameter!!))
|
||||
callStack.addInstruction(CompoundInstruction(it))
|
||||
|
||||
val newExpression = when (expression) {
|
||||
is IrCall -> IrCallImpl.fromSymbolOwner(expression.startOffset, expression.endOffset, expression.type, expression.symbol)
|
||||
is IrConstructorCall -> IrConstructorCallImpl.fromSymbolOwner(expression.type, expression.symbol)
|
||||
is IrDelegatingConstructorCall -> IrDelegatingConstructorCallImpl(0, 0, expression.type, expression.symbol, expression.typeArgumentsCount, expression.valueArgumentsCount)
|
||||
is IrEnumConstructorCall -> IrEnumConstructorCallImpl(0, 0, expression.type, expression.symbol, expression.typeArgumentsCount, expression.valueArgumentsCount)
|
||||
else -> TODO()
|
||||
}
|
||||
|
||||
expression.dispatchReceiver?.let {
|
||||
newExpression.dispatchReceiver = IrGetValueImpl(0, 0, defaultFun.dispatchReceiverParameter!!.type, defaultFun.dispatchReceiverParameter!!.symbol)
|
||||
}
|
||||
expression.extensionReceiver?.let {
|
||||
newExpression.extensionReceiver = IrGetValueImpl(0, 0, defaultFun.extensionReceiverParameter!!.type, defaultFun.extensionReceiverParameter!!.symbol)
|
||||
}
|
||||
val variablesForDefault = mutableListOf<IrVariable>()
|
||||
index = 0
|
||||
(0 until expression.valueArgumentsCount).forEach {
|
||||
val arg = if (expression.getValueArgument(it) != null) {
|
||||
IrGetValueImpl(0, 0, defaultFun.valueParameters[index].type, defaultFun.valueParameters[index++].symbol)
|
||||
} else {
|
||||
val init = getDefaultForParameterAt(it)
|
||||
?: expression.getVarargType(it)?.let { // case when value parameter is vararg and it is missing
|
||||
IrConstImpl.constNull(UNDEFINED_OFFSET, UNDEFINED_OFFSET, it)
|
||||
}
|
||||
val variable = IrVariableImpl(
|
||||
0, 0, IrDeclarationOrigin.IR_TEMPORARY_VARIABLE, IrVariableSymbolImpl(),
|
||||
irFunction.valueParameters[it].name, irFunction.valueParameters[it].type, isVar = false, isConst = false, isLateinit = false
|
||||
)
|
||||
variablesForDefault += variable
|
||||
parameters += variable
|
||||
variable.initializer = init
|
||||
IrGetValueImpl(0, 0, variable.type, variable.symbol)
|
||||
|
||||
}
|
||||
newExpression.putValueArgument(it, arg)
|
||||
}
|
||||
(0 until expression.typeArgumentsCount).forEach {
|
||||
newExpression.putTypeArgument(it, expression.getTypeArgument(it))
|
||||
}
|
||||
|
||||
|
||||
defaultFun.body = IrBlockBodyImpl(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET,
|
||||
variablesForDefault + IrReturnImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, defaultFun.returnType, defaultFun.symbol, newExpression)
|
||||
)
|
||||
|
||||
callStack.addInstruction(CompoundInstruction(callToDefault))
|
||||
} else {
|
||||
// new sub frame is used to store value arguments, in case then they are used in default args evaluation
|
||||
callStack.newSubFrame(expression) // TODO drop
|
||||
callStack.addInstruction(SimpleInstruction(expression))
|
||||
|
||||
fun IrValueParameter.schedule(arg: IrExpression?) {
|
||||
callStack.addInstruction(SimpleInstruction(this))
|
||||
callStack.addInstruction(CompoundInstruction(arg))
|
||||
}
|
||||
(expression.valueArgumentsCount - 1 downTo 0).forEach {
|
||||
irFunction.valueParameters[it].schedule(expression.getValueArgument(it))
|
||||
}
|
||||
expression.extensionReceiver?.let { irFunction.extensionReceiverParameter!!.schedule(it) }
|
||||
expression.dispatchReceiver?.let { irFunction.dispatchReceiverParameter!!.schedule(it) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -159,9 +159,6 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
||||
IllegalArgumentException("Parameter specified as non-null is null: method $method, parameter $parameter")
|
||||
} ?: return
|
||||
|
||||
//must add value argument in current stack because it can be used later as default argument
|
||||
callStack.addVariable(Variable(valueParameter.symbol, state))
|
||||
|
||||
// outer classes can be used in default args evaluation
|
||||
if (isReceiver() && state is Complex) state.loadOuterClassesInto(callStack)
|
||||
callStack.pushState(state)
|
||||
@@ -177,7 +174,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
||||
|
||||
val owner = call.symbol.owner
|
||||
// 1. load evaluated arguments from stack
|
||||
val valueArguments = owner.valueParameters.map { callStack.popState() }.reversed().toMutableList()
|
||||
val valueArguments = owner.valueParameters.map { callStack.popState() }.reversed()
|
||||
val extensionReceiver = owner.getExtensionReceiver()?.let { callStack.popState() }
|
||||
val dispatchReceiver = owner.getDispatchReceiver()?.let { callStack.popState() }
|
||||
|
||||
@@ -201,7 +198,7 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
||||
// 4. store arguments in memory (remap args on actual names)
|
||||
irFunction.getDispatchReceiver()?.let { dispatchReceiver?.let { receiver -> callStack.addVariable(Variable(it, receiver)) } }
|
||||
irFunction.getExtensionReceiver()?.let { callStack.addVariable(Variable(it, extensionReceiver ?: callStack.getState(it))) }
|
||||
irFunction.valueParameters.forEach { callStack.addVariable(Variable(it.symbol, valueArguments.removeFirst())) }
|
||||
irFunction.valueParameters.forEachIndexed { i, param -> callStack.addVariable(Variable(param.symbol, valueArguments[i])) }
|
||||
|
||||
// 5. store reified type parameters
|
||||
irFunction.typeParameters.filter { it.isReified }
|
||||
|
||||
+10
-8
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.stop
|
||||
@@ -227,16 +228,17 @@ internal object ArrayConstructor : IntrinsicBase() {
|
||||
val size = callStack.getState(sizeSymbol).asInt()
|
||||
|
||||
val initSymbol = irFunction.valueParameters[1].symbol
|
||||
val function = when (val state = callStack.getState(initSymbol)) {
|
||||
is KFunctionState -> state.irFunction.apply { callStack.loadUpValues(state) }
|
||||
is KPropertyState -> state.property.getter
|
||||
else -> TODO("Unsupported `init` in array constructor: $state")
|
||||
} as IrSimpleFunction
|
||||
val state = callStack.getState(initSymbol).let {
|
||||
(it as? KFunctionState) ?: (it as KPropertyState).convertGetterToKFunctionState()
|
||||
}
|
||||
// if property was converted, then we must replace symbol in memory to get correct receiver later
|
||||
callStack.setState(initSymbol, state)
|
||||
|
||||
for (i in size - 1 downTo 0) {
|
||||
val call = IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, function.returnType, function.symbol)
|
||||
val arg = IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, environment.irBuiltIns.intType, i)
|
||||
if (function.correspondingPropertySymbol == null) call.putValueArgument(0, arg) else call.extensionReceiver = arg
|
||||
val invoke = state.invokeSymbol.owner as IrSimpleFunction
|
||||
val call = IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, invoke.returnType, invoke.symbol)
|
||||
call.dispatchReceiver = IrGetValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, initSymbol)
|
||||
call.putValueArgument(0, IrConstImpl.int(UNDEFINED_OFFSET, UNDEFINED_OFFSET, environment.irBuiltIns.intType, i))
|
||||
instructions += CompoundInstruction(call)
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
package org.jetbrains.kotlin.ir.interpreter.state
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
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.IrCall
|
||||
@@ -93,5 +94,6 @@ internal fun State.checkNullability(
|
||||
}
|
||||
|
||||
internal fun State?.mustBeHandledAsReflection(call: IrCall): Boolean {
|
||||
if (call.symbol.owner.origin == IrDeclarationOrigin.FUNCTION_FOR_DEFAULT_PARAMETER) return false
|
||||
return this is ReflectionState && !(this is KFunctionState && call.symbol.owner.name == OperatorNameConventions.INVOKE)
|
||||
}
|
||||
+6
@@ -23,6 +23,12 @@ internal class KPropertyState(val property: IrProperty, override val irClass: Ir
|
||||
private var _parameters: List<KParameter>? = null
|
||||
private var _returnType: KType? = null
|
||||
|
||||
fun convertGetterToKFunctionState(): KFunctionState {
|
||||
val getterClass = irClass.getIrClassOfReflection("getter")
|
||||
val functionType = getterClass.superTypes.single { it.classOrNull?.owner?.name?.asString() == "Function1" }
|
||||
return KFunctionState(property.getter!!, functionType.classOrNull!!.owner)
|
||||
}
|
||||
|
||||
fun getParameters(callInterceptor: CallInterceptor): List<KParameter> {
|
||||
if (_parameters != null) return _parameters!!
|
||||
val kParameterIrClass = irClass.getIrClassOfReflectionFromList("parameters")
|
||||
|
||||
Reference in New Issue
Block a user