Implement basic interpretation for KProperty
This commit is contained in:
committed by
TeamCityServer
parent
c3d0438405
commit
41ea1525d1
@@ -4,7 +4,8 @@ plugins {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
compile(project(":compiler:ir.tree"))
|
||||
compileOnly(project(":compiler:ir.tree"))
|
||||
compileOnly(project(":kotlin-reflect-api"))
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.interpreter.exceptions.*
|
||||
import org.jetbrains.kotlin.ir.interpreter.intrinsics.IntrinsicEvaluator
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.wrap
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.StackImpl
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
@@ -140,6 +141,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
is IrStringConcatenation -> interpretStringConcatenation(this)
|
||||
is IrFunctionExpression -> interpretFunctionExpression(this)
|
||||
is IrFunctionReference -> interpretFunctionReference(this)
|
||||
is IrPropertyReference -> interpretPropertyReference(this)
|
||||
is IrComposite -> interpretComposite(this)
|
||||
|
||||
else -> TODO("${this.javaClass} not supported")
|
||||
@@ -317,6 +319,10 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
return@newFrame when {
|
||||
dispatchReceiver is Wrapper && !isInlineOnly -> dispatchReceiver.getMethod(irFunction).invokeMethod(irFunction)
|
||||
irFunction.hasAnnotation(evaluateIntrinsicAnnotation) -> Wrapper.getStaticMethod(irFunction).invokeMethod(irFunction)
|
||||
dispatchReceiver is ReflectionState -> {
|
||||
stack.pushReturnValue((dispatchReceiver.wrap(this) as ReflectionProxy).evaluate(expression, stack.getAll()))
|
||||
Next
|
||||
}
|
||||
dispatchReceiver is Primitive<*> -> calculateBuiltIns(irFunction) // 'is Primitive' check for js char and js long
|
||||
irFunction.body == null ->
|
||||
irFunction.trySubstituteFunctionBody() ?: irFunction.tryCalculateLazyConst() ?: calculateBuiltIns(irFunction)
|
||||
@@ -873,4 +879,12 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
else -> TODO("${expression.origin} not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
private fun interpretPropertyReference(propertyReference: IrPropertyReference): ExecutionResult {
|
||||
val dispatchReceiver = propertyReference.dispatchReceiver?.interpret()?.check { return it }?.let { stack.popReturnValue() }
|
||||
val extensionReceiver = propertyReference.extensionReceiver?.interpret()?.check { return it }?.let { stack.popReturnValue() }
|
||||
val propertyState = KPropertyState(propertyReference, dispatchReceiver, extensionReceiver)
|
||||
stack.pushReturnValue(propertyState)
|
||||
return Next
|
||||
}
|
||||
}
|
||||
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.ir.interpreter.proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.CommonProxy.Companion.asProxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.LambdaProxy.Companion.asProxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.ReflectionProxy.Companion.asProxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||
|
||||
internal interface Proxy {
|
||||
@@ -29,6 +30,7 @@ internal fun State.wrap(interpreter: IrInterpreter, extendFrom: Class<*>? = null
|
||||
is Primitive<*> -> this.value
|
||||
is Common -> this.asProxy(interpreter, extendFrom, calledFromBuiltIns)
|
||||
is Lambda -> this.asProxy(interpreter)
|
||||
is ReflectionState -> this.asProxy(interpreter)
|
||||
else -> throw AssertionError("${this::class} is unsupported as argument for wrap function")
|
||||
}
|
||||
}
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.ir.declarations.IrProperty
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import kotlin.reflect.KProperty
|
||||
import kotlin.reflect.KType
|
||||
import kotlin.reflect.KVisibility
|
||||
|
||||
internal abstract class AbstractKPropertyProxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : ReflectionProxy, KProperty<State> {
|
||||
private val propertyOwner: IrProperty
|
||||
get() = state.propertyReference.symbol.owner
|
||||
|
||||
override val isAbstract: Boolean
|
||||
get() = propertyOwner.modality == Modality.ABSTRACT
|
||||
override val isConst: Boolean
|
||||
get() = propertyOwner.isConst
|
||||
override val isFinal: Boolean
|
||||
get() = propertyOwner.modality == Modality.FINAL
|
||||
override val isLateinit: Boolean
|
||||
get() = propertyOwner.isLateinit
|
||||
override val isOpen: Boolean
|
||||
get() = propertyOwner.modality == Modality.OPEN
|
||||
override val isSuspend: Boolean
|
||||
get() = TODO("Not yet implemented")
|
||||
override val name: String
|
||||
get() = propertyOwner.name.asString()
|
||||
|
||||
override val annotations: List<Annotation>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val returnType: KType
|
||||
get() = TODO("Not yet implemented")
|
||||
override val visibility: KVisibility?
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty0Proxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : AbstractKPropertyProxy(state, interpreter), KProperty0<State> {
|
||||
override fun evaluate(expression: IrCall, args: List<Variable>): State {
|
||||
val result: Any = when (expression.symbol.owner.name.asString()) {
|
||||
"<get-name>" -> name
|
||||
"get" -> get()
|
||||
"invoke" -> invoke()
|
||||
else -> TODO("not supported expression for kProperty0")
|
||||
}
|
||||
|
||||
return result.toState(expression.type)
|
||||
}
|
||||
|
||||
override val getter: KProperty0.Getter<State>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val parameters: List<KParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val typeParameters: List<KTypeParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun call(vararg args: Any?): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun callBy(args: Map<KParameter, Any?>): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun get(): State {
|
||||
return state.dispatchReceiver!!.getState(state.propertyReference.symbol)!!
|
||||
}
|
||||
|
||||
override fun getDelegate(): Any? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun invoke(): State = get()
|
||||
}
|
||||
|
||||
internal class KMutableProperty0Proxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : KProperty0Proxy(state, interpreter), KMutableProperty0<State> {
|
||||
override fun evaluate(expression: IrCall, args: List<Variable>): State {
|
||||
val result: Any = when (expression.symbol.owner.name.asString()) {
|
||||
"set" -> set(args[1].state)
|
||||
else -> return super.evaluate(expression, args)
|
||||
}
|
||||
|
||||
return result.toState(expression.type)
|
||||
}
|
||||
|
||||
override val setter: KMutableProperty0.Setter<State>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun set(value: State) {
|
||||
state.dispatchReceiver!!.setField(Variable(state.propertyReference.symbol, value))
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty1Proxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : AbstractKPropertyProxy(state, interpreter), KProperty1<State, State> {
|
||||
override fun evaluate(expression: IrCall, args: List<Variable>): State {
|
||||
val result: Any = when (expression.symbol.owner.name.asString()) {
|
||||
"<get-name>" -> name
|
||||
"get" -> get(args[1].state)
|
||||
"invoke" -> invoke(args[1].state)
|
||||
else -> TODO("not supported expression for kProperty0")
|
||||
}
|
||||
|
||||
return result.toState(expression.type)
|
||||
}
|
||||
|
||||
override val getter: KProperty1.Getter<State, State>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val parameters: List<KParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val typeParameters: List<KTypeParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun call(vararg args: Any?): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun callBy(args: Map<KParameter, Any?>): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun get(receiver: State): State {
|
||||
return receiver.getState(state.propertyReference.symbol)!!
|
||||
}
|
||||
|
||||
override fun getDelegate(receiver: State): Any? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun invoke(p1: State): State = get(p1)
|
||||
}
|
||||
|
||||
internal class KMutableProperty1Proxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : KProperty1Proxy(state, interpreter), KMutableProperty1<State, State> {
|
||||
override fun evaluate(expression: IrCall, args: List<Variable>): State {
|
||||
val result: Any = when (expression.symbol.owner.name.asString()) {
|
||||
"set" -> set(args[1].state, args[2].state)
|
||||
else -> return super.evaluate(expression, args)
|
||||
}
|
||||
|
||||
return result.toState(expression.type)
|
||||
}
|
||||
|
||||
override val setter: KMutableProperty1.Setter<State, State>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun set(receiver: State, value: State) {
|
||||
receiver.setField(Variable(state.propertyReference.symbol, value))
|
||||
}
|
||||
}
|
||||
+74
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal open class KProperty2Proxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : AbstractKPropertyProxy(state, interpreter), KProperty2<State, State, State> {
|
||||
override fun evaluate(expression: IrCall, args: List<Variable>): State {
|
||||
val result: Any = when (expression.symbol.owner.name.asString()) {
|
||||
"<get-name>" -> name
|
||||
//"get" -> get()
|
||||
//"invoke" -> invoke()
|
||||
else -> TODO("not supported expression for kProperty0")
|
||||
}
|
||||
|
||||
return result.toState(expression.type)
|
||||
}
|
||||
|
||||
override val getter: KProperty2.Getter<State, State, State>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val parameters: List<KParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val typeParameters: List<KTypeParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun call(vararg args: Any?): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun callBy(args: Map<KParameter, Any?>): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun get(receiver1: State, receiver2: State): State {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun getDelegate(receiver1: State, receiver2: State): Any? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun invoke(p1: State, p2: State): State = get(p1, p2)
|
||||
}
|
||||
|
||||
internal class KMutableProperty2Proxy(
|
||||
override val state: KPropertyState, override val interpreter: IrInterpreter
|
||||
) : KProperty2Proxy(state, interpreter), KMutableProperty2<State, State, State> {
|
||||
override fun evaluate(expression: IrCall, args: List<Variable>): State {
|
||||
val result: Any = when (expression.symbol.owner.name.asString()) {
|
||||
//"set" -> set()
|
||||
else -> return super.evaluate(expression, args)
|
||||
}
|
||||
|
||||
return result.toState(expression.type)
|
||||
}
|
||||
|
||||
override val setter: KMutableProperty2.Setter<State, State, State>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun set(receiver1: State, receiver2: State, value: State) {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
+35
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.ReflectionState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.State
|
||||
|
||||
internal interface ReflectionProxy : Proxy {
|
||||
fun evaluate(expression: IrCall, args: List<Variable>): State
|
||||
|
||||
companion object {
|
||||
internal fun ReflectionState.asProxy(interpreter: IrInterpreter): ReflectionProxy {
|
||||
return when {
|
||||
this is KPropertyState -> when {
|
||||
this.isKProperty0() -> KProperty0Proxy(this, interpreter)
|
||||
this.isKMutableProperty0() -> KMutableProperty0Proxy(this, interpreter)
|
||||
this.isKProperty1() -> KProperty1Proxy(this, interpreter)
|
||||
this.isKMutableProperty1() -> KMutableProperty1Proxy(this, interpreter)
|
||||
this.isKProperty2() -> KProperty2Proxy(this, interpreter)
|
||||
this.isKMutableProperty2() -> KMutableProperty2Proxy(this, interpreter)
|
||||
else -> TODO()
|
||||
}
|
||||
else -> TODO("not supported reference state")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
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.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
|
||||
internal abstract class ReflectionState(override val irClass: IrClass) : State {
|
||||
override val fields: MutableList<Variable> = mutableListOf()
|
||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
||||
|
||||
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null
|
||||
}
|
||||
|
||||
internal class KPropertyState(
|
||||
val propertyReference: IrPropertyReference, val dispatchReceiver: State?, val extensionReceiver: State?
|
||||
) : ReflectionState(propertyReference.symbol.owner.parentAsClass) {
|
||||
val className = propertyReference.type.classOrNull?.owner?.name?.asString()
|
||||
|
||||
fun isKProperty0(): Boolean {
|
||||
return className == "KProperty0"
|
||||
}
|
||||
|
||||
fun isKProperty1(): Boolean {
|
||||
return className == "KProperty1"
|
||||
}
|
||||
|
||||
fun isKProperty2(): Boolean {
|
||||
return className == "KProperty2"
|
||||
}
|
||||
|
||||
fun isKMutableProperty0(): Boolean {
|
||||
return className == "KMutableProperty0"
|
||||
}
|
||||
|
||||
fun isKMutableProperty1(): Boolean {
|
||||
return className == "KMutableProperty1"
|
||||
}
|
||||
|
||||
fun isKMutableProperty2(): Boolean {
|
||||
return className == "KMutableProperty2"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user