diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt index 1e77b9096e6..33a32e18969 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt @@ -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 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 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 + 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 { @@ -709,7 +708,7 @@ class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map 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 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 diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt index ccc164dbed6..9eba505f6fb 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/Utils.kt @@ -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.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 { - 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() - ?.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 { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt index ade150b947e..52778be4ed3 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/intrinsics/IntrinsicImplementations.kt @@ -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().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().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 - 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(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(size) { if (irFunction.returnType.isCharArray()) 0.toChar() else 0 } + val arrayValue = MutableList(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 + } + } } } diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/CommonProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/CommonProxy.kt index 8352d47d26d..ae4aeca929f 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/CommonProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/CommonProxy.kt @@ -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) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Common.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Common.kt index dc1dbaee04e..455aa48713c 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Common.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Common.kt @@ -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) : Complex { override var superWrapperClass: Wrapper? = null - override val typeArguments: MutableList = mutableListOf() override var outerClass: Variable? = null constructor(irClass: IrClass) : this(irClass, mutableListOf()) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Complex.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Complex.kt index e8bede34d42..65bab793701 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Complex.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Complex.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.name.Name internal interface Complex: State { var superWrapperClass: Wrapper? - override val typeArguments: MutableList var outerClass: Variable? fun irClassFqName(): String { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt index e0dfbcb83fb..59dea4ab95c 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/ExceptionState.kt @@ -20,7 +20,6 @@ internal class ExceptionState private constructor( ) : Complex, Throwable() { override var superWrapperClass: Wrapper? = null - override val typeArguments: MutableList = mutableListOf() override var outerClass: Variable? = null override val message: String? diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt index cea91c8a04c..431c0fb54ea 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Primitive.kt @@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.util.overrides internal class Primitive(val value: T, val type: IrType) : State { override val fields: MutableList = mutableListOf() - override val typeArguments: MutableList = mutableListOf() override val irClass: IrClass = type.classOrNull!!.owner override fun getState(symbol: IrSymbol): State { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt index cdbbe4a9734..202ea09042f 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/State.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.ir.util.defaultType internal interface State { val fields: MutableList val irClass: IrClass - val typeArguments: MutableList fun getState(symbol: IrSymbol): State? { return fields.firstOrNull { it.symbol == symbol }?.state @@ -30,10 +29,6 @@ internal interface State { } } - fun addTypeArguments(typeArguments: List) { - 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!!) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt index 185531c3745..6f1739321e6 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/Wrapper.kt @@ -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 = mutableListOf() override var superWrapperClass: Wrapper? = null - override val typeArguments: MutableList = 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().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().single() + } + javaClass.canonicalName == "java.util.Collections.SingletonMap" -> { + javaClassToIrClass += AbstractMap.SimpleEntry::class.java to irClass.declarations.filterIsInstance().single() + javaClassToIrClass += AbstractMap.SimpleImmutableEntry::class.java to irClass.declarations.filterIsInstance().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("kotlin.text.Regex\$Companion" to Regex.Companion) + private val javaClassToIrClass = mutableMapOf, IrClass>() + + fun associateJavaClassWithIrClass(javaClass: Class<*>, irClass: IrClass) { + javaClassToIrClass += javaClass to irClass + } fun getReflectionMethod(irFunction: IrFunction): MethodHandle { val receiverClass = irFunction.dispatchReceiverParameter!!.type.getClass(asObject = true) diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt index 5b62d11e2be..67cc094cff4 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt @@ -27,7 +27,6 @@ import kotlin.reflect.KTypeParameter internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState() { override val fields: MutableList = mutableListOf() - override val typeArguments: MutableList = mutableListOf() private var _parameters: List? = null private var _returnType: KType? = null private var _typeParameters: List? = null diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeState.kt index 1196871a937..f538be5056b 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeState.kt @@ -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 { if (_arguments != null) return _arguments!! + Wrapper.associateJavaClassWithIrClass(KTypeProjection::class.java, irClass.getIrClassOfReflectionFromList("arguments")) _arguments = (irType as IrSimpleType).arguments .map { when (it.getVariance()) { diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/ReflectionState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/ReflectionState.kt index d6c15d86c65..b5060fbb37f 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/ReflectionState.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/ReflectionState.kt @@ -23,7 +23,6 @@ import org.jetbrains.kotlin.ir.util.parentClassOrNull internal abstract class ReflectionState : State { override val fields: MutableList = mutableListOf() - override val typeArguments: MutableList = mutableListOf() override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null