Add new intercept method in CallInterceptor for proxy

This commit is contained in:
Ivan Kylchik
2021-03-29 18:15:50 +03:00
committed by TeamCityServer
parent 25d01099d8
commit 285929ad07
21 changed files with 142 additions and 143 deletions
@@ -33,7 +33,10 @@ import java.lang.invoke.MethodHandle
internal interface CallInterceptor {
val environment: IrInterpreterEnvironment
val irBuiltIns: IrBuiltIns
val interpreter: IrInterpreter
fun interceptProxy(irFunction: IrFunction, valueArguments: List<Variable>, expectedResultClass: Class<*> = Any::class.java): Any?
fun interceptCall(call: IrCall, irFunction: IrFunction, receiver: State?, args: List<State>)
fun interceptConstructor(constructorCall: IrFunctionAccessExpression, receiver: State, args: List<State>)
fun interceptGetObjectValue(expression: IrGetObjectValue)
@@ -43,12 +46,16 @@ internal interface CallInterceptor {
internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) : CallInterceptor {
override val environment: IrInterpreterEnvironment = interpreter.environment
private val callStack: CallStack
get() = environment.callStack
private val irBuiltIns: IrBuiltIns
get() = environment.irBuiltIns
private val bodyMap: Map<IdSignature, IrBody>
get() = interpreter.bodyMap
private val callStack: CallStack = environment.callStack
override val irBuiltIns: IrBuiltIns = environment.irBuiltIns
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))
valueArguments.forEach { this@withNewCallStack.environment.callStack.addVariable(it) }
}.wrap(this@DefaultCallInterceptor, expectedResultClass)
}
override fun interceptCall(call: IrCall, irFunction: IrFunction, receiver: State?, args: List<State>) {
val isInlineOnly = irFunction.hasAnnotation(FqName("kotlin.internal.InlineOnly"))
@@ -126,7 +133,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
private fun MethodHandle?.invokeMethod(irFunction: IrFunction, args: List<State>) {
this ?: return handleIntrinsicMethods(irFunction)
val argsForMethodInvocation = irFunction.getArgsForMethodInvocation(interpreter, this.type(), args)
val argsForMethodInvocation = irFunction.getArgsForMethodInvocation(this@DefaultCallInterceptor, this.type(), args)
withExceptionHandler(environment) {
val result = this.invokeWithArguments(argsForMethodInvocation)
callStack.pushState(result.toState(result.getType(irFunction.returnType)))
@@ -145,7 +152,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
val receiverType = irFunction.dispatchReceiverParameter?.type
val argsType = listOfNotNull(receiverType) + irFunction.valueParameters.map { it.type }
val argsValues = args.map { it.wrap(interpreter, calledFromBuiltIns = methodName !in setOf("plus", IrBuiltIns.OperatorNames.EQEQ)) }
val argsValues = args.map { it.wrap(this, calledFromBuiltIns = methodName !in setOf("plus", IrBuiltIns.OperatorNames.EQEQ)) }
fun IrType.getOnlyName(): String {
return when {
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.ir.interpreter.exceptions.InterpreterError
import org.jetbrains.kotlin.ir.interpreter.exceptions.InterpreterTimeOutError
import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.*
@@ -82,16 +81,10 @@ class IrInterpreter private constructor(
return callStack.popState().toIrExpression(expression).apply { callStack.dropFrame() }
}
private fun withNewCallStack(block: IrInterpreter.() -> Any?): Any? {
internal fun withNewCallStack(frameOwner: IrFunction, init: IrInterpreter.() -> Any?): State {
return with(IrInterpreter(environment.copyWithNewCallStack(), bodyMap)) {
block()
}
}
internal fun IrFunction.proxyInterpret(valueArguments: List<Variable>, expectedResultClass: Class<*> = Any::class.java): Any? {
return withNewCallStack {
callStack.newFrame(this@proxyInterpret, listOf(CompoundInstruction(this@proxyInterpret)))
valueArguments.forEach { callStack.addVariable(it) }
callStack.newFrame(frameOwner, listOf())
init()
while (!callStack.hasNoInstructions()) {
callStack.popInstruction().handle()
@@ -99,7 +92,7 @@ class IrInterpreter private constructor(
}
if (callStack.peekState() == null) callStack.pushState(getUnitState()) // TODO maybe move this logic to body/block
callStack.popState().wrap(this@IrInterpreter, expectedResultClass).apply { callStack.dropFrame() }
callStack.popState().apply { callStack.dropFrame() }
}
}
@@ -462,7 +455,7 @@ class IrInterpreter private constructor(
}
is Common -> when {
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
else -> listOf(result.asProxy(this))
else -> listOf(result.asProxy(callInterceptor))
}
else -> listOf(result)
}
@@ -279,9 +279,11 @@ internal fun IrFunction?.checkCast(environment: IrInterpreterEnvironment): Boole
return true
}
internal fun IrFunction.getArgsForMethodInvocation(interpreter: IrInterpreter, methodType: MethodType, args: List<State>): List<Any?> {
internal fun IrFunction.getArgsForMethodInvocation(
callInterceptor: CallInterceptor, methodType: MethodType, args: List<State>
): List<Any?> {
val argsValues = args
.mapIndexed { index, state -> state.wrap(interpreter, methodType.parameterType(index)) }
.mapIndexed { index, state -> state.wrap(callInterceptor, methodType.parameterType(index)) }
.toMutableList()
// TODO if vararg isn't last parameter
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.ir.interpreter.proxy
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.*
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.getDispatchReceiver
import org.jetbrains.kotlin.ir.interpreter.internalName
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.Common
import org.jetbrains.kotlin.ir.interpreter.toState
@@ -20,7 +20,7 @@ import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny
* }
*/
internal class CommonProxy private constructor(
override val state: Common, override val interpreter: IrInterpreter, private val calledFromBuiltIns: Boolean = false
override val state: Common, override val callInterceptor: CallInterceptor, private val calledFromBuiltIns: Boolean = false
) : Proxy {
override fun equals(other: Any?): Boolean {
if (this === other) return true
@@ -33,7 +33,7 @@ internal class CommonProxy private constructor(
equalsFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
valueArguments.add(Variable(equalsFun.valueParameters.single().symbol, other.state))
return with(interpreter) { equalsFun.proxyInterpret(valueArguments) } as Boolean
return callInterceptor.interceptProxy(equalsFun, valueArguments) as Boolean
}
override fun hashCode(): Int {
@@ -42,7 +42,7 @@ internal class CommonProxy private constructor(
if (hashCodeFun.isFakeOverriddenFromAny() || calledFromBuiltIns) return System.identityHashCode(state)
hashCodeFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
return with(interpreter) { hashCodeFun.proxyInterpret(valueArguments) } as Int
return callInterceptor.interceptProxy(hashCodeFun, valueArguments) as Int
}
override fun toString(): String {
@@ -53,12 +53,14 @@ internal class CommonProxy private constructor(
}
toStringFun.getDispatchReceiver()!!.let { valueArguments.add(Variable(it, state)) }
return with(interpreter) { toStringFun.proxyInterpret(valueArguments) } as String
return callInterceptor.interceptProxy(toStringFun, valueArguments) as String
}
companion object {
internal fun Common.asProxy(interpreter: IrInterpreter, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false): Any {
val commonProxy = CommonProxy(this, interpreter, calledFromBuiltIns)
internal fun Common.asProxy(
callInterceptor: CallInterceptor, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false
): Any {
val commonProxy = CommonProxy(this, callInterceptor, calledFromBuiltIns)
val interfaces = when (extendFrom) {
null, Object::class.java -> arrayOf(Proxy::class.java)
@@ -68,7 +70,7 @@ internal class CommonProxy private constructor(
{ /*proxy*/_, method, args ->
when {
method.declaringClass == Proxy::class.java && method.name == "getState" -> commonProxy.state
method.declaringClass == Proxy::class.java && method.name == "getInterpreter" -> commonProxy.interpreter
method.declaringClass == Proxy::class.java && method.name == "getCallInterceptor" -> commonProxy.callInterceptor
method.name == "equals" && method.parameterTypes.single().isObject() -> commonProxy.equals(args.single())
method.name == "hashCode" && method.parameterTypes.isEmpty() -> commonProxy.hashCode()
method.name == "toString" && method.parameterTypes.isEmpty() -> commonProxy.toString()
@@ -79,7 +81,7 @@ internal class CommonProxy private constructor(
valueArguments += Variable(irFunction.getDispatchReceiver()!!, commonProxy.state)
valueArguments += irFunction.valueParameters
.mapIndexed { index, parameter -> Variable(parameter.symbol, args[index].toState(parameter.type)) }
with(interpreter) { irFunction.proxyInterpret(valueArguments, method.returnType) }
callInterceptor.interceptProxy(irFunction, valueArguments, method.returnType)
}
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.ir.interpreter.proxy
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy.Companion.asProxy
@@ -13,7 +14,7 @@ import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
internal interface Proxy {
val state: State
val interpreter: IrInterpreter
val callInterceptor: CallInterceptor
override fun equals(other: Any?): Boolean
override fun hashCode(): Int
@@ -23,13 +24,13 @@ internal interface Proxy {
/**
* Prepare state object to be passed in outer world
*/
internal fun State.wrap(interpreter: IrInterpreter, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false): Any? {
internal fun State.wrap(callInterceptor: CallInterceptor, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false): Any? {
return when (this) {
is ExceptionState -> this
is Wrapper -> this.value
is Primitive<*> -> this.value
is Common -> this.asProxy(interpreter, extendFrom, calledFromBuiltIns)
is ReflectionState -> this.asProxy(interpreter)
is Common -> this.asProxy(callInterceptor, extendFrom, calledFromBuiltIns)
is ReflectionState -> this.asProxy(callInterceptor)
else -> throw AssertionError("${this::class} is unsupported as argument for wrap function")
}
}
@@ -7,14 +7,14 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import kotlin.reflect.*
internal abstract class AbstractKPropertyProxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : ReflectionProxy, KProperty<Any?> {
protected val propertyType: IrType
get() = state.property.getter!!.returnType
@@ -37,9 +37,9 @@ internal abstract class AbstractKPropertyProxy(
override val annotations: List<Annotation>
get() = TODO("not implemented")
override val parameters: List<KParameter>
get() = state.getParameters(interpreter)
get() = state.getParameters(callInterceptor)
override val returnType: KType
get() = state.getReturnType(interpreter)
get() = state.getReturnType(callInterceptor)
override val typeParameters: List<KTypeParameter>
get() = listOf()
override val visibility: KVisibility?
@@ -6,14 +6,14 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.internalName
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KClassState
import kotlin.reflect.*
internal class KClassProxy(
override val state: KClassState, override val interpreter: IrInterpreter
override val state: KClassState, override val callInterceptor: CallInterceptor
) : ReflectionProxy, KClass<Proxy> {
override val simpleName: String?
get() = state.classReference.name.takeIf { !it.isSpecial }?.asString()
@@ -22,17 +22,17 @@ internal class KClassProxy(
@Suppress("UNCHECKED_CAST")
override val constructors: Collection<KFunction<Proxy>>
get() = state.getConstructors(interpreter) as Collection<KFunction<Proxy>>
get() = state.getConstructors(callInterceptor) as Collection<KFunction<Proxy>>
override val members: Collection<KCallable<*>>
get() = state.getMembers(interpreter)
get() = state.getMembers(callInterceptor)
override val nestedClasses: Collection<KClass<*>>
get() = TODO("Not yet implemented")
override val objectInstance: Proxy?
get() = TODO("Not yet implemented")
override val typeParameters: List<KTypeParameter>
get() = state.getTypeParameters(interpreter)
get() = state.getTypeParameters(callInterceptor)
override val supertypes: List<KType>
get() = state.getSupertypes(interpreter)
get() = state.getSupertypes(callInterceptor)
override val sealedSubclasses: List<KClass<out Proxy>>
get() = TODO("Not yet implemented")
override val annotations: List<Annotation>
@@ -8,7 +8,7 @@ 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.IrSimpleFunction
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
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
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.util.isSuspend
import kotlin.reflect.*
internal class KFunctionProxy(
override val state: KFunctionState, override val interpreter: IrInterpreter
override val state: KFunctionState, override val callInterceptor: CallInterceptor
) : ReflectionProxy, KFunction<Any?>, FunctionWithAllInvokes {
override val arity: Int = state.getArity() ?: BuiltInFunctionArity.BIG_ARITY
@@ -35,11 +35,11 @@ internal class KFunctionProxy(
override val annotations: List<Annotation>
get() = TODO("Not yet implemented")
override val parameters: List<KParameter>
get() = state.getParameters(interpreter)
get() = state.getParameters(callInterceptor)
override val returnType: KType
get() = state.getReturnType(interpreter)
get() = state.getReturnType(callInterceptor)
override val typeParameters: List<KTypeParameter>
get() = state.getTypeParameters(interpreter)
get() = state.getTypeParameters(callInterceptor)
override fun call(vararg args: Any?): Any? {
// TODO check arity
@@ -48,7 +48,7 @@ internal class KFunctionProxy(
val extensionReceiver = state.irFunction.extensionReceiverParameter?.let { Variable(it.symbol, args[index++].toState(it.type)) }
val valueArguments = listOfNotNull(dispatchReceiver, extensionReceiver) +
state.irFunction.valueParameters.map { parameter -> Variable(parameter.symbol, args[index++].toState(parameter.type)) }
return with(interpreter) { state.irFunction.proxyInterpret(valueArguments) }
return callInterceptor.interceptProxy(state.irFunction, valueArguments)
}
override fun callBy(args: Map<KParameter, Any?>): Any? {
@@ -5,18 +5,18 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KParameterState
import kotlin.reflect.KParameter
import kotlin.reflect.KType
internal class KParameterProxy(override val state: KParameterState, override val interpreter: IrInterpreter) : ReflectionProxy, KParameter {
internal class KParameterProxy(override val state: KParameterState, override val callInterceptor: CallInterceptor) : ReflectionProxy, KParameter {
override val index: Int
get() = state.index
override val name: String?
get() = if (kind == KParameter.Kind.VALUE) state.irParameter.name.asString() else null
override val type: KType
get() = state.getType(interpreter)
get() = state.getType(callInterceptor)
override val kind: KParameter.Kind
get() = state.kind
override val isOptional: Boolean
@@ -5,7 +5,7 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
import org.jetbrains.kotlin.ir.interpreter.toState
@@ -13,8 +13,8 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
import kotlin.reflect.*
internal open class KProperty0Proxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
) : AbstractKPropertyProxy(state, interpreter), KProperty0<Any?> {
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : AbstractKPropertyProxy(state, callInterceptor), KProperty0<Any?> {
override val getter: KProperty0.Getter<Any?>
get() = object : Getter(state.property.getter!!), KProperty0.Getter<Any?> {
override fun invoke(): Any? = call()
@@ -40,8 +40,8 @@ internal open class KProperty0Proxy(
}
internal class KMutableProperty0Proxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
) : KProperty0Proxy(state, interpreter), KMutableProperty0<Any?> {
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : KProperty0Proxy(state, callInterceptor), KMutableProperty0<Any?> {
override val setter: KMutableProperty0.Setter<Any?> =
object : Setter(state.property.setter!!), KMutableProperty0.Setter<Any?> {
override fun invoke(p1: Any?) = call(p1)
@@ -5,15 +5,15 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
import org.jetbrains.kotlin.ir.interpreter.toState
import kotlin.reflect.*
internal open class KProperty1Proxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
) : AbstractKPropertyProxy(state, interpreter), KProperty1<Any?, Any?> {
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : AbstractKPropertyProxy(state, callInterceptor), KProperty1<Any?, Any?> {
override val getter: KProperty1.Getter<Any?, Any?>
get() = object : Getter(state.property.getter!!), KProperty1.Getter<Any?, Any?> {
override fun invoke(p1: Any?): Any? = call(p1)
@@ -22,7 +22,7 @@ internal open class KProperty1Proxy(
checkArguments(1, args.size)
val receiverParameter = getter.dispatchReceiverParameter ?: getter.extensionReceiverParameter
val receiver = Variable(receiverParameter!!.symbol, args[0].toState(receiverParameter.type))
return with(this@KProperty1Proxy.interpreter) { getter.proxyInterpret(listOf(receiver)) }
return callInterceptor.interceptProxy(getter, listOf(receiver))
}
override fun callBy(args: Map<KParameter, Any?>): Any? {
@@ -40,8 +40,8 @@ internal open class KProperty1Proxy(
}
internal class KMutableProperty1Proxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
) : KProperty1Proxy(state, interpreter), KMutableProperty1<Any?, Any?> {
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : KProperty1Proxy(state, callInterceptor), KMutableProperty1<Any?, Any?> {
override val setter: KMutableProperty1.Setter<Any?, Any?> =
object : Setter(state.property.setter!!), KMutableProperty1.Setter<Any?, Any?> {
override fun invoke(p1: Any?, p2: Any?) = call(p1, p2)
@@ -52,7 +52,7 @@ internal class KMutableProperty1Proxy(
val receiver = Variable(receiverParameter!!.symbol, args[0].toState(receiverParameter.type))
val valueParameter = setter.valueParameters.single()
val value = Variable(valueParameter.symbol, args[1].toState(valueParameter.type))
with(this@KMutableProperty1Proxy.interpreter) { setter.proxyInterpret(listOf(receiver, value)) }
callInterceptor.interceptProxy(setter, listOf(receiver, value))
}
override fun callBy(args: Map<KParameter, Any?>) {
@@ -5,15 +5,15 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
import org.jetbrains.kotlin.ir.interpreter.toState
import kotlin.reflect.*
internal open class KProperty2Proxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
) : AbstractKPropertyProxy(state, interpreter), KProperty2<Any?, Any?, Any?> {
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : AbstractKPropertyProxy(state, callInterceptor), KProperty2<Any?, Any?, Any?> {
override val getter: KProperty2.Getter<Any?, Any?, Any?>
get() = object : Getter(state.property.getter!!), KProperty2.Getter<Any?, Any?, Any?> {
override fun invoke(p1: Any?, p2: Any?): Any? = call(p1, p2)
@@ -22,7 +22,7 @@ internal open class KProperty2Proxy(
checkArguments(2, args.size)
val dispatch = Variable(getter.dispatchReceiverParameter!!.symbol, args[0].toState(getter.dispatchReceiverParameter!!.type))
val extension = Variable(getter.extensionReceiverParameter!!.symbol, args[1].toState(getter.extensionReceiverParameter!!.type))
return with(this@KProperty2Proxy.interpreter) { getter.proxyInterpret(listOf(dispatch, extension)) }
return callInterceptor.interceptProxy(getter, listOf(dispatch, extension))
}
override fun callBy(args: Map<KParameter, Any?>): Any? {
@@ -40,8 +40,8 @@ internal open class KProperty2Proxy(
}
internal class KMutableProperty2Proxy(
override val state: KPropertyState, override val interpreter: IrInterpreter
) : KProperty2Proxy(state, interpreter), KMutableProperty2<Any?, Any?, Any?> {
override val state: KPropertyState, override val callInterceptor: CallInterceptor
) : KProperty2Proxy(state, callInterceptor), KMutableProperty2<Any?, Any?, Any?> {
override val setter: KMutableProperty2.Setter<Any?, Any?, Any?>
get() = object : Setter(state.property.setter!!), KMutableProperty2.Setter<Any?, Any?, Any?> {
override fun invoke(p1: Any?, p2: Any?, p3: Any?) = call(p1, p2, p3)
@@ -5,18 +5,18 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeParameterState
import org.jetbrains.kotlin.types.Variance
import kotlin.reflect.*
internal class KTypeParameterProxy(
override val state: KTypeParameterState, override val interpreter: IrInterpreter
override val state: KTypeParameterState, override val callInterceptor: CallInterceptor
) : ReflectionProxy, KTypeParameter {
override val name: String
get() = state.irTypeParameter.name.asString()
override val upperBounds: List<KType>
get() = state.getUpperBounds(interpreter)
get() = state.getUpperBounds(callInterceptor)
override val variance: KVariance
get() = when (state.irTypeParameter.variance) {
Variance.INVARIANT -> KVariance.INVARIANT
@@ -5,23 +5,18 @@
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KClassState
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeParameterState
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState
import org.jetbrains.kotlin.ir.types.classifierOrFail
import org.jetbrains.kotlin.ir.types.isMarkedNullable
import kotlin.reflect.KClassifier
import kotlin.reflect.KType
import kotlin.reflect.KTypeProjection
internal class KTypeProxy(override val state: KTypeState, override val interpreter: IrInterpreter) : ReflectionProxy, KType {
internal class KTypeProxy(override val state: KTypeState, override val callInterceptor: CallInterceptor) : ReflectionProxy, KType {
override val classifier: KClassifier?
get() = state.getClassifier(interpreter)
get() = state.getClassifier(callInterceptor)
override val arguments: List<KTypeProjection>
get() = state.getArguments(interpreter)
get() = state.getArguments(callInterceptor)
override val isMarkedNullable: Boolean
get() = state.irType.isMarkedNullable()
override val annotations: List<Annotation>
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
import org.jetbrains.kotlin.ir.interpreter.state.reflection.*
import kotlin.reflect.KVisibility
@@ -24,22 +24,22 @@ internal interface ReflectionProxy : Proxy {
}
companion object {
internal fun ReflectionState.asProxy(interpreter: IrInterpreter): ReflectionProxy {
internal fun ReflectionState.asProxy(callInterceptor: CallInterceptor): ReflectionProxy {
return when (this) {
is KPropertyState -> when {
this.isKMutableProperty0() -> KMutableProperty0Proxy(this, interpreter)
this.isKProperty0() -> KProperty0Proxy(this, interpreter)
this.isKMutableProperty1() -> KMutableProperty1Proxy(this, interpreter)
this.isKProperty1() -> KProperty1Proxy(this, interpreter)
this.isKMutableProperty2() -> KMutableProperty2Proxy(this, interpreter)
this.isKProperty2() -> KProperty2Proxy(this, interpreter)
this.isKMutableProperty0() -> KMutableProperty0Proxy(this, callInterceptor)
this.isKProperty0() -> KProperty0Proxy(this, callInterceptor)
this.isKMutableProperty1() -> KMutableProperty1Proxy(this, callInterceptor)
this.isKProperty1() -> KProperty1Proxy(this, callInterceptor)
this.isKMutableProperty2() -> KMutableProperty2Proxy(this, callInterceptor)
this.isKProperty2() -> KProperty2Proxy(this, callInterceptor)
else -> TODO()
}
is KFunctionState -> KFunctionProxy(this, interpreter)
is KClassState -> KClassProxy(this, interpreter)
is KTypeState -> KTypeProxy(this, interpreter)
is KTypeParameterState -> KTypeParameterProxy(this, interpreter)
is KParameterState -> KParameterProxy(this, interpreter)
is KFunctionState -> KFunctionProxy(this, callInterceptor)
is KClassState -> KClassProxy(this, callInterceptor)
is KTypeState -> KTypeProxy(this, callInterceptor)
is KTypeParameterState -> KTypeParameterProxy(this, callInterceptor)
is KParameterState -> KParameterProxy(this, callInterceptor)
else -> TODO("not supported reference state")
}
}
@@ -10,9 +10,8 @@ import org.jetbrains.kotlin.ir.declarations.IrConstructor
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.expressions.IrClassReference
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.internalName
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.*
import org.jetbrains.kotlin.ir.types.classOrNull
import kotlin.reflect.KCallable
@@ -28,7 +27,7 @@ internal class KClassState(val classReference: IrClass, override val irClass: Ir
constructor(classReference: IrClassReference) : this(classReference.symbol.owner as IrClass, classReference.type.classOrNull!!.owner)
fun getMembers(interpreter: IrInterpreter): Collection<KCallable<*>> {
fun getMembers(callInterceptor: CallInterceptor): Collection<KCallable<*>> {
if (_members != null) return _members!!
_members = classReference.declarations
.filter { it !is IrClass && it !is IrConstructor }
@@ -38,47 +37,47 @@ internal class KClassState(val classReference: IrClass, override val irClass: Ir
val withExtension = it.getter?.extensionReceiverParameter != null
when {
!withExtension && !it.isVar ->
KProperty1Proxy(KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(false, 1).owner), interpreter)
KProperty1Proxy(KPropertyState(it, callInterceptor.irBuiltIns.getKPropertyClass(false, 1).owner), callInterceptor)
!withExtension && it.isVar ->
KMutableProperty1Proxy(
KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(true, 1).owner), interpreter
KPropertyState(it, callInterceptor.irBuiltIns.getKPropertyClass(true, 1).owner), callInterceptor
)
withExtension && !it.isVar ->
KProperty2Proxy(KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(false, 2).owner), interpreter)
KProperty2Proxy(KPropertyState(it, callInterceptor.irBuiltIns.getKPropertyClass(false, 2).owner), callInterceptor)
!withExtension && it.isVar ->
KMutableProperty2Proxy(
KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(true, 2).owner), interpreter
KPropertyState(it, callInterceptor.irBuiltIns.getKPropertyClass(true, 2).owner), callInterceptor
)
else -> TODO()
}
}
is IrFunction -> KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter)
is IrFunction -> KFunctionProxy(KFunctionState(it, callInterceptor.irBuiltIns.functionFactory), callInterceptor)
else -> TODO()
}
}
return _members!!
}
fun getConstructors(interpreter: IrInterpreter): Collection<KFunction<*>> {
fun getConstructors(callInterceptor: CallInterceptor): Collection<KFunction<*>> {
if (_constructors != null) return _constructors!!
_constructors = classReference.declarations
.filterIsInstance<IrConstructor>()
.map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) }
.map { KFunctionProxy(KFunctionState(it, callInterceptor.irBuiltIns.functionFactory), callInterceptor) }
return _constructors!!
}
fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> {
fun getTypeParameters(callInterceptor: CallInterceptor): List<KTypeParameter> {
if (_typeParameters != null) return _typeParameters!!
val kTypeParameterIrClass = irClass.getIrClassOfReflectionFromList("typeParameters")
_typeParameters = classReference.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it, kTypeParameterIrClass), interpreter) }
_typeParameters = classReference.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it, kTypeParameterIrClass), callInterceptor) }
return _typeParameters!!
}
fun getSupertypes(interpreter: IrInterpreter): List<KType> {
fun getSupertypes(callInterceptor: CallInterceptor): List<KType> {
if (_supertypes != null) return _supertypes!!
val kTypeIrClass = irClass.getIrClassOfReflectionFromList("supertypes")
_supertypes = (classReference.superTypes.map { it } + interpreter.irBuiltIns.anyType).toSet()
.map { KTypeProxy(KTypeState(it, kTypeIrClass), interpreter) }
_supertypes = (classReference.superTypes.map { it } + callInterceptor.irBuiltIns.anyType).toSet()
.map { KTypeProxy(KTypeState(it, kTypeIrClass), callInterceptor) }
return _supertypes!!
}
@@ -10,7 +10,7 @@ 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.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KParameterProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
@@ -33,30 +33,30 @@ internal class KFunctionState(val irFunction: IrFunction, override val irClass:
constructor(irFunction: IrFunction, functionFactory: IrAbstractFunctionFactory) :
this(irFunction, functionFactory.kFunctionN(irFunction.valueParameters.size))
fun getParameters(interpreter: IrInterpreter): List<KParameter> {
fun getParameters(callInterceptor: CallInterceptor): List<KParameter> {
if (_parameters != null) return _parameters!!
val kParameterIrClass = irClass.getIrClassOfReflectionFromList("parameters")
var index = 0
val instanceParameter = irFunction.dispatchReceiverParameter
?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.INSTANCE), interpreter) }
?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.INSTANCE), callInterceptor) }
val extensionParameter = irFunction.extensionReceiverParameter
?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.EXTENSION_RECEIVER), interpreter) }
?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.EXTENSION_RECEIVER), callInterceptor) }
_parameters = listOfNotNull(instanceParameter, extensionParameter) +
irFunction.valueParameters.map { KParameterProxy(KParameterState(kParameterIrClass, it, index++), interpreter) }
irFunction.valueParameters.map { KParameterProxy(KParameterState(kParameterIrClass, it, index++), callInterceptor) }
return _parameters!!
}
fun getReturnType(interpreter: IrInterpreter): KType {
fun getReturnType(callInterceptor: CallInterceptor): KType {
if (_returnType != null) return _returnType!!
val kTypeIrClass = irClass.getIrClassOfReflection("returnType")
_returnType = KTypeProxy(KTypeState(irFunction.returnType, kTypeIrClass), interpreter)
_returnType = KTypeProxy(KTypeState(irFunction.returnType, kTypeIrClass), callInterceptor)
return _returnType!!
}
fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> {
fun getTypeParameters(callInterceptor: CallInterceptor): List<KTypeParameter> {
if (_typeParameters != null) return _typeParameters!!
val kTypeParametersIrClass = irClass.getIrClassOfReflectionFromList("typeParameters")
_typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it, kTypeParametersIrClass), interpreter) }
_typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it, kTypeParametersIrClass), callInterceptor) }
return _typeParameters!!
}
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
import kotlin.reflect.KParameter
import kotlin.reflect.KType
@@ -16,10 +16,10 @@ internal class KParameterState(
) : ReflectionState() {
private var _type: KType? = null
fun getType(interpreter: IrInterpreter): KType {
fun getType(callInterceptor: CallInterceptor): KType {
if (_type != null) return _type!!
val kTypeIrClass = irClass.getIrClassOfReflection("type")
_type = KTypeProxy(KTypeState(irParameter.type, kTypeIrClass), interpreter)
_type = KTypeProxy(KTypeState(irParameter.type, kTypeIrClass), callInterceptor)
return _type!!
}
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KParameterProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
import org.jetbrains.kotlin.ir.interpreter.state.State
@@ -26,22 +26,22 @@ internal class KPropertyState(
private var _parameters: List<KParameter>? = null
private var _returnType: KType? = null
fun getParameters(interpreter: IrInterpreter): List<KParameter> {
fun getParameters(callInterceptor: CallInterceptor): List<KParameter> {
if (_parameters != null) return _parameters!!
val kParameterIrClass = irClass.getIrClassOfReflectionFromList("parameters")
var index = 0
val instanceParameter = property.getter?.dispatchReceiverParameter?.takeIf { dispatchReceiver == null }
?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.INSTANCE), interpreter) }
?.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), interpreter) }
?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.EXTENSION_RECEIVER), callInterceptor) }
_parameters = listOfNotNull(instanceParameter, extensionParameter)
return _parameters!!
}
fun getReturnType(interpreter: IrInterpreter): KType {
fun getReturnType(callInterceptor: CallInterceptor): KType {
if (_returnType != null) return _returnType!!
val kTypeIrClass = irClass.getIrClassOfReflection("returnType")
_returnType = KTypeProxy(KTypeState(property.getter!!.returnType, kTypeIrClass), interpreter)
_returnType = KTypeProxy(KTypeState(property.getter!!.returnType, kTypeIrClass), callInterceptor)
return _returnType!!
}
@@ -7,17 +7,17 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
import kotlin.reflect.KType
internal class KTypeParameterState(val irTypeParameter: IrTypeParameter, override val irClass: IrClass) : ReflectionState() {
private var _upperBounds: List<KType>? = null
fun getUpperBounds(interpreter: IrInterpreter): List<KType> {
fun getUpperBounds(callInterceptor: CallInterceptor): List<KType> {
if (_upperBounds != null) return _upperBounds!!
val kTypeIrClass = irClass.getIrClassOfReflectionFromList("upperBounds")
_upperBounds = irTypeParameter.superTypes.map { KTypeProxy(KTypeState(it, kTypeIrClass), interpreter) }
_upperBounds = irTypeParameter.superTypes.map { KTypeProxy(KTypeState(it, kTypeIrClass), callInterceptor) }
return _upperBounds!!
}
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.CallInterceptor
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KClassProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
@@ -22,28 +22,28 @@ internal class KTypeState(val irType: IrType, override val irClass: IrClass) : R
private var _classifier: KClassifier? = null
private var _arguments: List<KTypeProjection>? = null
fun getClassifier(interpreter: IrInterpreter): KClassifier? {
fun getClassifier(callInterceptor: CallInterceptor): KClassifier? {
if (_classifier != null) return _classifier!!
_classifier = when (val classifier = irType.classifierOrFail.owner) {
is IrClass -> KClassProxy(KClassState(classifier, interpreter.irBuiltIns.kClassClass.owner), interpreter)
is IrClass -> KClassProxy(KClassState(classifier, callInterceptor.irBuiltIns.kClassClass.owner), callInterceptor)
is IrTypeParameter -> {
val kTypeParameterIrClass = interpreter.irBuiltIns.kClassClass.owner.getIrClassOfReflectionFromList("typeParameters")
KTypeParameterProxy(KTypeParameterState(classifier, kTypeParameterIrClass), interpreter)
val kTypeParameterIrClass = callInterceptor.irBuiltIns.kClassClass.owner.getIrClassOfReflectionFromList("typeParameters")
KTypeParameterProxy(KTypeParameterState(classifier, kTypeParameterIrClass), callInterceptor)
}
else -> TODO()
}
return _classifier!!
}
fun getArguments(interpreter: IrInterpreter): List<KTypeProjection> {
fun getArguments(callInterceptor: CallInterceptor): List<KTypeProjection> {
if (_arguments != null) return _arguments!!
Wrapper.associateJavaClassWithIrClass(KTypeProjection::class.java, irClass.getIrClassOfReflectionFromList("arguments"))
_arguments = (irType as IrSimpleType).arguments
.map {
when (it.getVariance()) {
Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter))
Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter))
Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter))
Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), callInterceptor))
Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), callInterceptor))
Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), callInterceptor))
null -> KTypeProjection.STAR
}
}