Remove typeArguments field in State interface

This commit is contained in:
Ivan Kylchik
2020-10-01 13:23:53 +03:00
committed by TeamCityServer
parent a10d88924f
commit 9d9ab498aa
13 changed files with 106 additions and 116 deletions
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
import org.jetbrains.kotlin.ir.interpreter.stack.StackImpl
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.*
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KClassState
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
import org.jetbrains.kotlin.ir.interpreter.state.reflection.*
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
@@ -67,10 +64,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
is Float -> irBuiltIns.floatType
is Double -> irBuiltIns.doubleType
null -> irBuiltIns.nothingNType
else -> when (defaultType.classifierOrNull?.owner) {
is IrTypeParameter -> stack.getVariable(defaultType.classifierOrFail).state.irClass.defaultType
else -> defaultType
}
else -> defaultType
}
}
@@ -228,8 +222,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
else -> throw InterpreterError("Unsupported number of arguments for invocation as builtin functions")
}
}
val typeArguments = if (methodName == "CHECK_NOT_NULL") args.single().typeArguments else listOf()
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)).apply { addTypeArguments(typeArguments) })
stack.pushReturnValue(result.toState(result.getType(irFunction.returnType)))
return Next
}
@@ -305,9 +298,15 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
interpretValueParameters(expression, irFunction, valueArguments).check { return it }
valueArguments.addAll(getTypeArguments(irFunction, expression) { stack.getVariable(it).state })
if (dispatchReceiver is Complex) valueArguments.addAll(dispatchReceiver.typeArguments)
if (extensionReceiver is Complex) valueArguments.addAll(extensionReceiver.typeArguments)
irFunction.typeParameters
.filter {
it.isReified || irFunction.fqNameWhenAvailable.toString().let { it == "kotlin.emptyArray" || it == "kotlin.ArrayIntrinsicsKt.emptyArray" }
}
.forEach {
// TODO: emptyArray check is a hack for js, because in js-ir its type parameter isn't marked as reified
// TODO: if using KTypeState then it's class must be corresponding
valueArguments.add(Variable(it.symbol, KTypeState(expression.getTypeArgument(it.index)!!, irBuiltIns.anyClass.owner)))
}
if (dispatchReceiver?.irClass?.isLocal == true || irFunction.isLocal) {
valueArguments.addAll(dispatchReceiver.extractNonLocalDeclarations())
@@ -382,16 +381,17 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
interpretValueParameters(constructorCall, owner, valueArguments).check { return it }
val irClass = owner.parent as IrClass
val typeArguments = getTypeArguments(irClass, constructorCall) { stack.getVariable(it).state }
if (irClass.hasAnnotation(evaluateIntrinsicAnnotation) || irClass.fqNameWhenAvailable!!.startsWith(Name.identifier("java"))) {
return stack.newFrame(initPool = valueArguments) { Wrapper.getConstructorMethod(owner).invokeMethod(owner) }
.apply { stack.peekReturnValue().addTypeArguments(typeArguments) }
}
if (irClass.defaultType.isArray() || irClass.defaultType.isPrimitiveArray()) {
// array constructor doesn't have body so must be treated separately
return stack.newFrame(initPool = valueArguments) { handleIntrinsicMethods(owner) }
.apply { stack.peekReturnValue().addTypeArguments(typeArguments) }
.apply {
val array = stack.popReturnValue() as Primitive<*>
stack.pushReturnValue(Primitive(array.value, constructorCall.type))
}
}
if (irClass.defaultType.isUnsignedType() && valueArguments.size == 1 && owner.valueParameters.size == 1) {
@@ -402,7 +402,6 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
}
val state = stack.getVariable(constructorCall.getThisReceiver()).state as Common
state.addTypeArguments(typeArguments)
if (irClass.isLocal) {
state.fields.addAll(stack.getAll()) // TODO save only necessary declarations
@@ -419,7 +418,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
}
valueArguments.add(Variable(constructorCall.getThisReceiver(), state)) //used to set up fields in body
return stack.newFrame(initPool = valueArguments + state.typeArguments) {
return stack.newFrame(initPool = valueArguments) {
val statements = constructorCall.getBody()!!.statements
when (val irStatement = statements[0]) {
is IrTypeOperatorCall -> {
@@ -709,7 +708,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
val typeClassifier = expression.typeOperand.classifierOrFail
val isReified = (typeClassifier.owner as? IrTypeParameter)?.isReified == true
val isErased = typeClassifier.owner is IrTypeParameter && !isReified
val typeOperand = if (isReified) stack.getVariable(typeClassifier).state.irClass.defaultType else expression.typeOperand
val typeOperand = if (isReified) (stack.getVariable(typeClassifier).state as KTypeState).irType else expression.typeOperand
when (expression.operator) {
// coercion to unit means that return value isn't used
@@ -758,18 +757,17 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
}
}
val elementIrClass = expression.varargElementType.classOrNull
val args = expression.elements.flatMap {
it.interpret().check { executionResult -> return executionResult }
return@flatMap when (val result = stack.popReturnValue()) {
is Wrapper -> listOf(result.value)
is Primitive<*> -> when {
expression.varargElementType.isArray() -> listOf(result.value)
expression.varargElementType.isArray() -> listOf(result)
else -> arrayToList(result.value)
}
is Common -> when {
result.irClass.defaultType.isUnsignedArray() -> arrayToList((result.fields.single().state as Primitive<*>).value)
else -> listOf(result.asProxy(this, elementIrClass?.owner))
else -> listOf(result.asProxy(this))
}
else -> listOf(result)
}
@@ -788,13 +786,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSigna
val unsignedArray = primitiveArray.toPrimitiveStateArray(storageProperty.backingField!!.type)
Common(owner).apply { fields.add(Variable(storageProperty.symbol, unsignedArray)) }
}
else -> args.toPrimitiveStateArray(expression.type).apply {
if (expression.type.isArray()) {
val arrayTypeArgument = elementIrClass?.let { Common(it.owner) }
?: stack.getVariable(expression.varargElementType.classifierOrFail).state
this.addTypeArguments(listOf(Variable(irBuiltIns.arrayClass.owner.typeParameters.single().symbol, arrayTypeArgument)))
}
}
else -> args.toPrimitiveStateArray(expression.type)
}
stack.pushReturnValue(array)
return Next
@@ -21,9 +21,12 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
import org.jetbrains.kotlin.ir.symbols.*
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.lang.invoke.MethodType
@@ -71,7 +74,7 @@ internal fun Any?.toState(irType: IrType): State {
is Boolean, is Char, is Byte, is Short, is Int, is Long, is String, is Float, is Double, is Array<*>, is ByteArray,
is CharArray, is ShortArray, is IntArray, is LongArray, is FloatArray, is DoubleArray, is BooleanArray -> Primitive(this, irType)
null -> Primitive(this, irType)
else -> Wrapper(this, irType.classOrNull!!.owner)
else -> irType.classOrNull?.owner?.let { Wrapper(this, it) } ?: Wrapper(this)
}
}
@@ -163,38 +166,11 @@ internal fun List<Any?>.toPrimitiveStateArray(type: IrType): Primitive<*> {
fun IrFunctionAccessExpression.getVarargType(index: Int): IrType? {
val varargType = this.symbol.owner.valueParameters[index].varargElementType ?: return null
varargType.classOrNull?.let { return this.symbol.owner.valueParameters[index].type }
val typeParameter = varargType.classifierOrFail.owner as IrTypeParameter
return this.getTypeArgument(typeParameter.index)
}
internal fun getTypeArguments(
container: IrTypeParametersContainer, expression: IrFunctionAccessExpression, mapper: (IrTypeParameterSymbol) -> State
): List<Variable> {
fun IrType.getState(): State {
return this.classOrNull?.owner?.let { Common(it) } ?: mapper(this.classifierOrFail as IrTypeParameterSymbol)
val type = this.symbol.owner.valueParameters[index].type as? IrSimpleType ?: return null
return type.buildSimpleType {
val typeParameter = varargType.classifierOrFail.owner as IrTypeParameter
arguments = listOf(makeTypeProjection(this@getVarargType.getTypeArgument(typeParameter.index)!!, Variance.OUT_VARIANCE))
}
val typeArguments = container.typeParameters.mapIndexed { index, typeParameter ->
val typeArgument = expression.getTypeArgument(index)!!
Variable(typeParameter.symbol, typeArgument.getState())
}.toMutableList()
if (container is IrSimpleFunction) {
container.returnType.classifierOrFail.owner.safeAs<IrTypeParameter>()
?.let { typeArguments.add(Variable(it.symbol, expression.type.getState())) }
}
fun IrSimpleType.getArgumentsRecursive() {
val typeParameters = this.classOrNull?.owner?.typeParameters ?: return
typeParameters.zip(this.arguments).forEach {
it.second.typeOrNull?.classOrNull?.owner?.let { owner -> typeArguments.add(Variable(it.first.symbol, Common(owner))) }
}
this.classOrNull!!.superTypes().forEach { (it as? IrSimpleType)?.getArgumentsRecursive() }
}
(container as? IrClass)?.superTypes?.forEach { (it as? IrSimpleType)?.getArgumentsRecursive() }
return typeArguments
}
internal fun State?.extractNonLocalDeclarations(): List<Variable> {
@@ -15,8 +15,15 @@ import org.jetbrains.kotlin.ir.declarations.IrEnumEntry
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.interpreter.exceptions.throwAsUserException
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.makeTypeProjection
import org.jetbrains.kotlin.ir.types.isArray
import org.jetbrains.kotlin.ir.types.isCharArray
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.types.Variance
internal sealed class IntrinsicBase {
abstract fun equalTo(irFunction: IrFunction): Boolean
@@ -30,8 +37,11 @@ internal object EmptyArray : IntrinsicBase() {
}
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
stack.pushReturnValue(emptyArray<Any?>().toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
val typeArgument = irFunction.typeParameters.map { stack.getVariable(it.symbol) }.single().state as KTypeState
val returnType = (irFunction.returnType as IrSimpleType).buildSimpleType {
arguments = listOf(makeTypeProjection(typeArgument.irType, Variance.INVARIANT))
}
stack.pushReturnValue(emptyArray<Any?>().toState(returnType))
return Next
}
}
@@ -44,9 +54,7 @@ internal object ArrayOf : IntrinsicBase() {
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
val elementsVariable = irFunction.valueParameters.single().symbol
val array = (stack.getVariable(elementsVariable).state as Primitive<*>).value as Array<out Any?>
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
stack.pushReturnValue(array.toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
stack.pushReturnValue(stack.getVariable(elementsVariable).state)
return Next
}
}
@@ -60,8 +68,11 @@ internal object ArrayOfNulls : IntrinsicBase() {
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
val size = stack.getVariable(irFunction.valueParameters.first().symbol).state.asInt()
val array = arrayOfNulls<Any?>(size)
val typeArguments = irFunction.typeParameters.map { stack.getVariable(it.symbol) }
stack.pushReturnValue(array.toState(irFunction.returnType).apply { addTypeArguments(typeArguments) })
val typeArgument = irFunction.typeParameters.map { stack.getVariable(it.symbol) }.single().state as KTypeState
val returnType = (irFunction.returnType as IrSimpleType).buildSimpleType {
arguments = listOf(makeTypeProjection(typeArgument.irType, Variance.INVARIANT))
}
stack.pushReturnValue(array.toState(returnType))
return Next
}
}
@@ -74,7 +85,10 @@ internal object EnumValues : IntrinsicBase() {
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
"kotlin.enumValues" -> stack.getVariable(irFunction.typeParameters.first().symbol).state.irClass
"kotlin.enumValues" -> {
val kType = stack.getVariable(irFunction.typeParameters.first().symbol).state as KTypeState
kType.irType.classOrNull!!.owner
}
else -> irFunction.parent as IrClass
}
@@ -93,7 +107,10 @@ internal object EnumValueOf : IntrinsicBase() {
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
val enumClass = when (irFunction.fqNameWhenAvailable.toString()) {
"kotlin.enumValueOf" -> stack.getVariable(irFunction.typeParameters.first().symbol).state.irClass
"kotlin.enumValueOf" -> {
val kType = stack.getVariable(irFunction.typeParameters.first().symbol).state as KTypeState
kType.irType.classOrNull!!.owner
}
else -> irFunction.parent as IrClass
}
val enumEntryName = stack.getVariable(irFunction.valueParameters.first().symbol).state.asString()
@@ -149,7 +166,7 @@ internal object ArrayConstructor : IntrinsicBase() {
override fun evaluate(irFunction: IrFunction, stack: Stack, interpret: IrElement.() -> ExecutionResult): ExecutionResult {
val sizeDescriptor = irFunction.valueParameters[0].symbol
val size = stack.getVariable(sizeDescriptor).state.asInt()
val arrayValue = MutableList<Any>(size) { if (irFunction.returnType.isCharArray()) 0.toChar() else 0 }
val arrayValue = MutableList<Any?>(size) { if (irFunction.returnType.isCharArray()) 0.toChar() else 0 }
if (irFunction.valueParameters.size == 2) {
val initDescriptor = irFunction.valueParameters[1].symbol
@@ -163,7 +180,13 @@ internal object ArrayConstructor : IntrinsicBase() {
asSubFrame = initLambda.irFunction.isLocal || initLambda.irFunction.isInline,
initPool = nonLocalDeclarations + indexVar
) { initLambda.irFunction.body!!.interpret() }.check(ReturnLabel.RETURN) { return it }
arrayValue[i] = stack.popReturnValue().let { (it as? Wrapper)?.value ?: (it as? Primitive<*>)?.value ?: it }
arrayValue[i] = stack.popReturnValue().let {
when (it) {
is Wrapper -> it.value
is Primitive<*> -> if (it.type.isArray() || it.type.isPrimitiveArray()) it else it.value
else -> it
}
}
}
}
@@ -5,20 +5,13 @@
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:
@@ -64,25 +57,6 @@ 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)
@@ -8,15 +8,12 @@ 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.interpreter.getLastOverridden
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
internal class Common private constructor(override val irClass: IrClass, override val fields: MutableList<Variable>) : Complex {
override var superWrapperClass: Wrapper? = null
override val typeArguments: MutableList<Variable> = mutableListOf()
override var outerClass: Variable? = null
constructor(irClass: IrClass) : this(irClass, mutableListOf())
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.name.Name
internal interface Complex: State {
var superWrapperClass: Wrapper?
override val typeArguments: MutableList<Variable>
var outerClass: Variable?
fun irClassFqName(): String {
@@ -20,7 +20,6 @@ internal class ExceptionState private constructor(
) : Complex, Throwable() {
override var superWrapperClass: Wrapper? = null
override val typeArguments: MutableList<Variable> = mutableListOf()
override var outerClass: Variable? = null
override val message: String?
@@ -21,7 +21,6 @@ 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 typeArguments: MutableList<Variable> = mutableListOf()
override val irClass: IrClass = type.classOrNull!!.owner
override fun getState(symbol: IrSymbol): State {
@@ -17,7 +17,6 @@ import org.jetbrains.kotlin.ir.util.defaultType
internal interface State {
val fields: MutableList<Variable>
val irClass: IrClass
val typeArguments: MutableList<Variable>
fun getState(symbol: IrSymbol): State? {
return fields.firstOrNull { it.symbol == symbol }?.state
@@ -30,10 +29,6 @@ internal interface State {
}
}
fun addTypeArguments(typeArguments: List<Variable>) {
this.typeArguments.addAll(typeArguments)
}
fun getIrFunctionByIrCall(expression: IrCall): IrFunction?
}
@@ -51,10 +46,15 @@ internal fun State.isSubtypeOf(other: IrType): Boolean {
if (this is ExceptionState) return this.isSubtypeOf(other.classOrNull!!.owner)
if (this is Primitive<*> && this.type.isArray() && other.isArray()) {
val thisClass = this.typeArguments.single().state.irClass.symbol
val otherArgument = (other as IrSimpleType).arguments.single()
if (otherArgument is IrStarProjection) return true
return otherArgument.typeOrNull?.classOrNull?.let { thisClass.isSubtypeOfClass(it) } ?: true
fun IrType.arraySubtypeCheck(other: IrType): Boolean {
if (other !is IrSimpleType || this !is IrSimpleType) return false
val thisArgument = this.arguments.single().typeOrNull ?: return false
val otherArgument = other.arguments.single().typeOrNull ?: return other.arguments.single() is IrStarProjection
if (thisArgument.isArray() && otherArgument.isArray()) return thisArgument.arraySubtypeCheck(otherArgument)
if (otherArgument.classOrNull == null) return false
return thisArgument.classOrNull?.isSubtypeOfClass(otherArgument.classOrNull!!) ?: false
}
return this.type.arraySubtypeCheck(other)
}
return this.irClass.defaultType.isSubtypeOfClass(other.classOrNull!!)
@@ -18,21 +18,47 @@ import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.defaultType
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
import org.jetbrains.kotlin.ir.util.isInterface
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
import java.lang.invoke.MethodHandle
import java.lang.invoke.MethodHandles
import java.lang.invoke.MethodType
import java.util.*
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap
internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex {
override val fields: MutableList<Variable> = mutableListOf()
override var superWrapperClass: Wrapper? = null
override val typeArguments: MutableList<Variable> = mutableListOf()
override var outerClass: Variable? = null
private val receiverClass = irClass.defaultType.getClass(true)
init {
val javaClass = value::class.java
when {
javaClass == HashMap::class.java -> {
val nodeClass = javaClass.declaredClasses.single { it.name.contains("\$Node") }
val mutableMap = irClass.superTypes.mapNotNull { it.classOrNull?.owner }.single { it.isInterface }
javaClassToIrClass += nodeClass to mutableMap.declarations.filterIsInstance<IrClass>().single()
}
javaClass == LinkedHashMap::class.java -> {
val entryClass = javaClass.declaredClasses.single { it.name.contains("\$Entry") }
val mutableMap = irClass.superTypes.mapNotNull { it.classOrNull?.owner }.single { it.isInterface }
javaClassToIrClass += entryClass to mutableMap.declarations.filterIsInstance<IrClass>().single()
}
javaClass.canonicalName == "java.util.Collections.SingletonMap" -> {
javaClassToIrClass += AbstractMap.SimpleEntry::class.java to irClass.declarations.filterIsInstance<IrClass>().single()
javaClassToIrClass += AbstractMap.SimpleImmutableEntry::class.java to irClass.declarations.filterIsInstance<IrClass>().single()
}
}
javaClassToIrClass += value::class.java to irClass
}
constructor(value: Any) : this(value, javaClassToIrClass[value::class.java]!!)
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
fun getMethod(irFunction: IrFunction): MethodHandle? {
@@ -65,6 +91,11 @@ internal class Wrapper(val value: Any, override val irClass: IrClass) : Complex
companion object {
private val companionObjectValue = mapOf<String, Any>("kotlin.text.Regex\$Companion" to Regex.Companion)
private val javaClassToIrClass = mutableMapOf<Class<*>, IrClass>()
fun associateJavaClassWithIrClass(javaClass: Class<*>, irClass: IrClass) {
javaClassToIrClass += javaClass to irClass
}
fun getReflectionMethod(irFunction: IrFunction): MethodHandle {
val receiverClass = irFunction.dispatchReceiverParameter!!.type.getClass(asObject = true)
@@ -27,7 +27,6 @@ import kotlin.reflect.KTypeParameter
internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState() {
override val fields: MutableList<Variable> = mutableListOf()
override val typeArguments: MutableList<Variable> = mutableListOf()
private var _parameters: List<KParameter>? = null
private var _returnType: KType? = null
private var _typeParameters: List<KTypeParameter>? = null
@@ -12,6 +12,7 @@ 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
import org.jetbrains.kotlin.ir.interpreter.renderType
import org.jetbrains.kotlin.ir.interpreter.state.Wrapper
import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.types.Variance
import kotlin.reflect.KClassifier
@@ -36,6 +37,7 @@ internal class KTypeState(val irType: IrType, override val irClass: IrClass) : R
fun getArguments(interpreter: IrInterpreter): List<KTypeProjection> {
if (_arguments != null) return _arguments!!
Wrapper.associateJavaClassWithIrClass(KTypeProjection::class.java, irClass.getIrClassOfReflectionFromList("arguments"))
_arguments = (irType as IrSimpleType).arguments
.map {
when (it.getVariance()) {
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.ir.util.parentClassOrNull
internal abstract class ReflectionState : State {
override val fields: MutableList<Variable> = mutableListOf()
override val typeArguments: MutableList<Variable> = mutableListOf()
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null