Support proper subtype check in interpreter for KFunction
This commit is contained in:
committed by
TeamCityServer
parent
9638af042d
commit
574c607f1c
@@ -7,15 +7,20 @@ 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.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||
import org.jetbrains.kotlin.ir.interpreter.exceptions.handleUserException
|
||||
import org.jetbrains.kotlin.ir.interpreter.isFunction
|
||||
import org.jetbrains.kotlin.ir.interpreter.isKFunction
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KFunctionState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.reflection.ReflectionState
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
internal interface State {
|
||||
@@ -62,7 +67,15 @@ internal fun State.isSubtypeOf(other: IrType): Boolean {
|
||||
return this.type.arraySubtypeCheck(other)
|
||||
}
|
||||
|
||||
return this.irClass.defaultType.isSubtypeOfClass(other.classOrNull!!)
|
||||
val thisType = this.irClass.defaultType
|
||||
if (other.isFunction() && thisType.isKFunction()/* TODO || (other.isSuspendFunction && thisType.isKSuspendFunction())*/) {
|
||||
// KFunction{n} has no super type of Function{n},
|
||||
// but the single overridden function of KFunction{n}.invoke is Function{n}.invoke.
|
||||
val invokeFun = this.irClass.declarations.filterIsInstance<IrSimpleFunction>().single { it.name == OperatorNameConventions.INVOKE }
|
||||
return invokeFun.overriddenSymbols.single().owner.parentAsClass.isSubclassOf(other.classOrNull!!.owner)
|
||||
}
|
||||
|
||||
return thisType.isSubtypeOfClass(other.classOrNull!!)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
+14
-2
@@ -6,8 +6,8 @@ open class A : Base
|
||||
@CompileTimeCalculation
|
||||
class B : A()
|
||||
|
||||
const val a1 = 1 is Int
|
||||
const val a2 = 2 !is Int
|
||||
const val a1 = <!EVALUATED: `true`!>{ 1 is Int }()<!> // avoid evaluation by native interpreter
|
||||
const val a2 = <!EVALUATED: `false`!>{ 2 !is Int }()<!>
|
||||
|
||||
const val b1 = <!EVALUATED: `true`!>A() is Base<!>
|
||||
const val b2 = <!EVALUATED: `false`!>A() !is Base<!>
|
||||
@@ -20,3 +20,15 @@ const val c3 = <!EVALUATED: `true`!>B() is A<!>
|
||||
const val c4 = <!EVALUATED: `false`!>B() !is A<!>
|
||||
const val c5 = <!EVALUATED: `true`!>B() is B<!>
|
||||
const val c6 = <!EVALUATED: `false`!>B() !is B<!>
|
||||
|
||||
@CompileTimeCalculation
|
||||
fun foo(): Unit {}
|
||||
@CompileTimeCalculation
|
||||
fun bar(p1: Int): Unit {}
|
||||
|
||||
const val d1 =<!EVALUATED: `true`!>::foo is kotlin.reflect.KFunction<*><!>
|
||||
const val d2 =<!EVALUATED: `true`!>::foo is Function0<*><!>
|
||||
const val d3 =<!EVALUATED: `false`!>::foo is Function1<*, *><!>
|
||||
const val d4 =<!EVALUATED: `true`!>::bar is kotlin.reflect.KFunction<*><!>
|
||||
const val d5 =<!EVALUATED: `false`!>::bar is Function0<*><!>
|
||||
const val d6 =<!EVALUATED: `true`!>::bar is Function1<*, *><!>
|
||||
|
||||
Reference in New Issue
Block a user