Fix property rendering in interpreter
This commit is contained in:
committed by
TeamCityServer
parent
af67e950c4
commit
59fefb6214
+2
-4
@@ -94,9 +94,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
|
||||
val function = when (val symbol = invokedFunction.symbol) {
|
||||
is IrSimpleFunctionSymbol -> {
|
||||
val irCall = IrCallImpl.fromSymbolOwner(
|
||||
UNDEFINED_OFFSET, UNDEFINED_OFFSET, invokedFunction.returnType, invokedFunction.symbol as IrSimpleFunctionSymbol
|
||||
)
|
||||
val irCall = IrCallImpl.fromSymbolOwner(UNDEFINED_OFFSET, UNDEFINED_OFFSET, invokedFunction.returnType, symbol)
|
||||
val actualFunction = dispatchReceiver?.getIrFunctionByIrCall(irCall) ?: invokedFunction
|
||||
callStack.newFrame(actualFunction)
|
||||
callStack.addInstruction(SimpleInstruction(actualFunction))
|
||||
@@ -118,6 +116,7 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
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])) }
|
||||
if (invokedFunction.symbol is IrConstructorSymbol) return
|
||||
|
||||
callStack.loadUpValues(functionState)
|
||||
if (extensionReceiver is StateWithClosure) callStack.loadUpValues(extensionReceiver)
|
||||
@@ -125,7 +124,6 @@ internal class DefaultCallInterceptor(override val interpreter: IrInterpreter) :
|
||||
generateSequence(dispatchReceiver.outerClass) { (it.state as? Complex)?.outerClass }.forEach { callStack.addVariable(it) }
|
||||
}
|
||||
|
||||
if (invokedFunction.symbol is IrConstructorSymbol) return
|
||||
this.interceptCall(call, function, listOfNotNull(dispatchReceiver, extensionReceiver) + valueArguments) {
|
||||
callStack.addInstruction(CompoundInstruction(function))
|
||||
}
|
||||
|
||||
@@ -426,6 +426,7 @@ class IrInterpreter private constructor(
|
||||
|
||||
val cleanEnumSuperCall = fun() {
|
||||
enumSuperCall?.apply { (0 until this.valueArgumentsCount).forEach { putValueArgument(it, null) } } // restore to null
|
||||
callStack.popState() // result of constructor must be dropped, because next instruction will be `IrGetEnumValue`
|
||||
callStack.dropSubFrame()
|
||||
}
|
||||
|
||||
@@ -606,6 +607,16 @@ class IrInterpreter private constructor(
|
||||
|
||||
callStack.dropSubFrame()
|
||||
val propertyState = KPropertyState(propertyReference, receiver)
|
||||
|
||||
fun List<IrTypeParameter>.addToFields() {
|
||||
(0 until propertyReference.typeArgumentsCount).forEach { index ->
|
||||
val kTypeState = KTypeState(propertyReference.getTypeArgument(index)!!, irBuiltIns.anyClass.owner)
|
||||
propertyState.fields += Variable(this[index].symbol, kTypeState)
|
||||
}
|
||||
}
|
||||
propertyReference.getter?.owner?.typeParameters?.addToFields()
|
||||
propertyReference.setter?.owner?.typeParameters?.addToFields()
|
||||
|
||||
callStack.pushState(propertyState)
|
||||
}
|
||||
|
||||
|
||||
+2
@@ -13,6 +13,7 @@ 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.isObject
|
||||
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||
import kotlin.reflect.*
|
||||
|
||||
@@ -66,6 +67,7 @@ internal class KMutableProperty0Proxy(
|
||||
checkArguments(1, args.size)
|
||||
// null receiver <=> property is on top level
|
||||
verify(state.receiver != null) { "Cannot interpret set method on top level properties" }
|
||||
verify(state.receiver?.irClass?.isObject != true) { "Cannot interpret set method on property of object" }
|
||||
val receiver = state.receiver!!
|
||||
val newValue = args.single().toState(propertyType)
|
||||
setter.getExtensionReceiver()
|
||||
|
||||
+17
-5
@@ -5,23 +5,35 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrValueParameter
|
||||
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.state.reflection.KTypeState
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty1Proxy(
|
||||
override val state: KPropertyState, override val callInterceptor: CallInterceptor
|
||||
) : AbstractKPropertyProxy(state, callInterceptor), KProperty1<Any?, Any?> {
|
||||
protected fun IrValueParameter.getActualType(): IrType {
|
||||
return when (this.type.classOrNull) {
|
||||
null -> (state.getField(this.type.classifierOrFail) as KTypeState).irType
|
||||
else -> this.type
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
override fun call(vararg args: Any?): Any? {
|
||||
checkArguments(1, args.size)
|
||||
val receiverParameter = getter.dispatchReceiverParameter ?: getter.extensionReceiverParameter
|
||||
val receiver = Variable(receiverParameter!!.symbol, args[0].toState(receiverParameter.type))
|
||||
val receiverParameter = (getter.dispatchReceiverParameter ?: getter.extensionReceiverParameter)!!
|
||||
val receiver = Variable(receiverParameter.symbol, args[0].toState(receiverParameter.getActualType()))
|
||||
return callInterceptor.interceptProxy(getter, listOf(receiver))
|
||||
}
|
||||
|
||||
@@ -48,10 +60,10 @@ internal class KMutableProperty1Proxy(
|
||||
|
||||
override fun call(vararg args: Any?) {
|
||||
checkArguments(2, args.size)
|
||||
val receiverParameter = setter.dispatchReceiverParameter ?: setter.extensionReceiverParameter
|
||||
val receiver = Variable(receiverParameter!!.symbol, args[0].toState(receiverParameter.type))
|
||||
val receiverParameter = (setter.dispatchReceiverParameter ?: setter.extensionReceiverParameter)!!
|
||||
val receiver = Variable(receiverParameter.symbol, args[0].toState(receiverParameter.getActualType()))
|
||||
val valueParameter = setter.valueParameters.single()
|
||||
val value = Variable(valueParameter.symbol, args[1].toState(valueParameter.type))
|
||||
val value = Variable(valueParameter.symbol, args[1].toState(valueParameter.getActualType()))
|
||||
callInterceptor.interceptProxy(setter, listOf(receiver, value))
|
||||
}
|
||||
|
||||
|
||||
+12
-8
@@ -42,16 +42,15 @@ internal abstract class ReflectionState : State {
|
||||
private fun renderReceivers(dispatchReceiver: IrType?, extensionReceiver: IrType?): String {
|
||||
return buildString {
|
||||
if (dispatchReceiver != null) {
|
||||
append(dispatchReceiver.renderType())
|
||||
append(".")
|
||||
append(dispatchReceiver.renderType()).append(".")
|
||||
}
|
||||
val addParentheses = dispatchReceiver != null && extensionReceiver != null
|
||||
if (addParentheses) append("(")
|
||||
|
||||
if (extensionReceiver != null) {
|
||||
append(extensionReceiver.renderType())
|
||||
append(".")
|
||||
val addParentheses = dispatchReceiver != null
|
||||
if (addParentheses) append("(")
|
||||
append(extensionReceiver.renderType()).append(".")
|
||||
if (addParentheses) append(")")
|
||||
}
|
||||
if (addParentheses) append(")")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,7 +78,12 @@ internal abstract class ReflectionState : State {
|
||||
}
|
||||
|
||||
protected fun IrType.renderType(): String {
|
||||
var renderedType = this.render()
|
||||
var renderedType = this.render().replace("<root>.", "")
|
||||
if (renderedType.contains("<get-")) {
|
||||
val startIndex = renderedType.indexOf("<get-")
|
||||
val lastTriangle = renderedType.indexOf('>', startIndex) + 1
|
||||
renderedType = renderedType.replaceRange(startIndex, lastTriangle, "get")
|
||||
}
|
||||
do {
|
||||
val index = renderedType.indexOf(" of ")
|
||||
if (index == -1) break
|
||||
|
||||
@@ -23,3 +23,10 @@ const val mutablePropertyWithReceiverName = B(10)::b.<!EVALUATED: `b`!>name<!>
|
||||
const val mutablePropertyWithReceiverGet = B(11)::b.<!EVALUATED: `11`!>get()<!>
|
||||
const val mutablePropertyWithReceiverSet = B(12).apply { this::b.set(13) }.<!EVALUATED: `13`!>b<!>
|
||||
const val mutablePropertyWithReceiverInvoke = B(14)::b.<!EVALUATED: `14`!>invoke()<!>
|
||||
|
||||
@CompileTimeCalculation
|
||||
var <T> T.bar : T
|
||||
get() = this
|
||||
set(value) { }
|
||||
|
||||
const val barToString = String::bar.<!EVALUATED: `var T.bar: T`!>toString()<!>
|
||||
|
||||
Reference in New Issue
Block a user