Implement simple proxy for non interface structures like kotlin.Pair
This commit is contained in:
committed by
TeamCityServer
parent
1e5096294e
commit
d931e2eead
@@ -701,6 +701,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
}
|
||||
}
|
||||
|
||||
val elementIrClass = expression.varargElementType.classOrNull
|
||||
val args = expression.elements.flatMap {
|
||||
it.interpret().check { executionResult -> return executionResult }
|
||||
return@flatMap when (val result = stack.popReturnValue()) {
|
||||
@@ -708,7 +709,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
is Primitive<*> -> arrayToList(result.value)
|
||||
is Common -> when {
|
||||
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
|
||||
else -> listOf(result.asProxy(this))
|
||||
else -> listOf(result.asProxy(this, elementIrClass?.owner))
|
||||
}
|
||||
else -> listOf(result)
|
||||
}
|
||||
@@ -729,7 +730,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
}
|
||||
else -> args.toPrimitiveStateArray(expression.type).apply {
|
||||
if (expression.type.isArray()) {
|
||||
val arrayTypeArgument = expression.varargElementType.classOrNull?.let { Common(it.owner) }
|
||||
val arrayTypeArgument = elementIrClass?.let { Common(it.owner) }
|
||||
?: stack.getVariable(expression.varargElementType.classifierOrFail).state
|
||||
this.addTypeArguments(listOf(Variable(irBuiltIns.arrayClass.owner.typeParameters.single().symbol, arrayTypeArgument)))
|
||||
}
|
||||
|
||||
+26
@@ -5,13 +5,20 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy
|
||||
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
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
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.isAny
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.isFakeOverriddenFromAny
|
||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||
|
||||
/**
|
||||
* calledFromBuiltIns - used to avoid cyclic calls. For example:
|
||||
@@ -57,6 +64,25 @@ internal class CommonProxy private constructor(
|
||||
}
|
||||
|
||||
companion object {
|
||||
internal fun Common.asProxy(interpreter: IrInterpreter, extendFrom: IrClass?): Any {
|
||||
val elementType = when {
|
||||
extendFrom?.defaultType?.isAny() == false -> {
|
||||
val fqName = extendFrom.fqNameForIrSerialization.asString()
|
||||
if (fqName.startsWith("kotlin")) Class.forName(fqName) else null
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
|
||||
return when (elementType) {
|
||||
Pair::class.java -> {
|
||||
val first = this.irClass.declarations.single { it.nameForIrSerialization.asString() == "first" } as IrSymbolOwner
|
||||
val second = this.irClass.declarations.single { it.nameForIrSerialization.asString() == "second" } as IrSymbolOwner
|
||||
Pair(this.getState(first.symbol), this.getState(second.symbol))
|
||||
}
|
||||
else -> this.asProxy(interpreter)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Common.asProxy(interpreter: IrInterpreter, extendFrom: Class<*>? = null, calledFromBuiltIns: Boolean = false): Any {
|
||||
val commonProxy = CommonProxy(this, interpreter, calledFromBuiltIns)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user