Support cast to array with reified argument in interpreter
This commit is contained in:
committed by
TeamCityServer
parent
cc56acc2c2
commit
b10fdb919f
+19
-5
@@ -20,12 +20,11 @@ import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.CallStack
|
||||
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.KTypeState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.*
|
||||
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
|
||||
internal interface Instruction {
|
||||
@@ -438,10 +437,25 @@ class IrInterpreter(internal val environment: IrInterpreterEnvironment, internal
|
||||
}
|
||||
|
||||
private fun interpretTypeOperatorCall(expression: IrTypeOperatorCall) {
|
||||
fun IrClassifierSymbol.getTypeFromStack(): IrType {
|
||||
return (callStack.getState(this) as KTypeState).irType
|
||||
}
|
||||
|
||||
fun IrType.replaceArgumentIfReified(): IrType {
|
||||
if (this !is IrSimpleType) return this
|
||||
val argument = this.arguments.singleOrNull()?.typeOrNull?.classifierOrNull
|
||||
return when {
|
||||
argument is IrTypeParameterSymbol && argument.owner.isReified -> {
|
||||
this.buildSimpleType { arguments = listOf(argument.getTypeFromStack() as IrTypeArgument) }
|
||||
}
|
||||
else -> this
|
||||
}
|
||||
}
|
||||
|
||||
val typeClassifier = expression.typeOperand.classifierOrFail
|
||||
val isReified = (typeClassifier.owner as? IrTypeParameter)?.isReified == true
|
||||
val isErased = typeClassifier.owner is IrTypeParameter && !isReified
|
||||
val typeOperand = if (isReified) (callStack.getState(typeClassifier) as KTypeState).irType else expression.typeOperand
|
||||
val typeOperand = (if (isReified) typeClassifier.getTypeFromStack() else expression.typeOperand).replaceArgumentIfReified()
|
||||
|
||||
val state = callStack.popState()
|
||||
when (expression.operator) {
|
||||
|
||||
@@ -10,6 +10,8 @@ inline fun <reified T> bar(): String {
|
||||
return if (listOf<Int>() as? T == null) "Can't cast" else "Safe cast"
|
||||
}
|
||||
|
||||
inline fun <reified T> arrayCast(vararg t: T): Array<T> = t as Array<T>
|
||||
|
||||
const val a1 = <!EVALUATED: `Safe cast`!>foo<Int>()<!>
|
||||
const val a2 = <!EVALUATED: `Safe cast`!>foo<Int?>()<!>
|
||||
const val a3 = <!EVALUATED: `Safe cast`!>foo<Double?>()<!>
|
||||
@@ -31,3 +33,7 @@ const val c5 = <!EVALUATED: `true`!>arrayOf<List<Int>>(listOf(1, 2), listOf(2, 3
|
||||
const val c6 = <!EVALUATED: `false`!>arrayOf<List<Int>>(listOf(1, 2), listOf(2, 3)) as? Array<Collection<String>> == null<!>
|
||||
const val c7 = <!EVALUATED: `false`!>Array<List<Int>>(3) { listOf(it, it + 1) } as? Array<List<String>?> == null<!>
|
||||
const val c8 = <!EVALUATED: `true`!>Array<List<Int>>(3) { listOf(it, it + 1) } as? Array<Set<Int>> == null<!>
|
||||
|
||||
const val d1 = arrayCast(arrayOf<Int>(1, 2, 3)).<!EVALUATED: `1`!>size<!>
|
||||
const val d2 = arrayCast(*arrayOf<Int>(1, 2, 3)).<!EVALUATED: `3`!>size<!>
|
||||
const val d3 = arrayCast<Int>(1, 2, 3).<!EVALUATED: `3`!>size<!>
|
||||
|
||||
Reference in New Issue
Block a user