Implement basic interpretation of IrClassReference
This commit is contained in:
committed by
TeamCityServer
parent
002804941f
commit
40bf4fafc9
@@ -34,7 +34,7 @@ import java.lang.invoke.MethodHandle
|
||||
private const val MAX_COMMANDS = 500_000
|
||||
private const val MAX_STACK = 500
|
||||
|
||||
class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSignature, IrBody> = emptyMap()) {
|
||||
class IrInterpreter(val irBuiltIns: IrBuiltIns, private val bodyMap: Map<IdSignature, IrBody> = emptyMap()) {
|
||||
private val irExceptions = mutableListOf<IrClass>()
|
||||
|
||||
private val stack = StackImpl()
|
||||
@@ -142,6 +142,7 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
is IrFunctionExpression -> interpretFunctionExpression(this)
|
||||
is IrFunctionReference -> interpretFunctionReference(this)
|
||||
is IrPropertyReference -> interpretPropertyReference(this)
|
||||
is IrClassReference -> interpretClassReference(this)
|
||||
is IrComposite -> interpretComposite(this)
|
||||
|
||||
else -> TODO("${this.javaClass} not supported")
|
||||
@@ -889,4 +890,9 @@ class IrInterpreter(private val irBuiltIns: IrBuiltIns, private val bodyMap: Map
|
||||
stack.pushReturnValue(propertyState)
|
||||
return Next
|
||||
}
|
||||
|
||||
private fun interpretClassReference(classReference: IrClassReference): ExecutionResult {
|
||||
stack.pushReturnValue(KClassState(classReference))
|
||||
return Next
|
||||
}
|
||||
}
|
||||
+3
-2
@@ -29,7 +29,7 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
|
||||
WITH_ANNOTATIONS(mustCheckBody = false) {
|
||||
override fun canEvaluateFunction(function: IrFunction, expression: IrCall?): Boolean {
|
||||
if (function.isCompileTimeProperty()) return true
|
||||
return function.isMarkedWith(compileTimeAnnotation) || function.origin == IrBuiltIns.BUILTIN_OPERATOR ||
|
||||
return function.isMarkedAsCompileTime() || function.origin == IrBuiltIns.BUILTIN_OPERATOR ||
|
||||
(function is IrSimpleFunction && function.isOperator && function.name.asString() == "invoke") ||
|
||||
(function is IrSimpleFunction && function.isFakeOverride && function.overriddenSymbols.any { canEvaluateFunction(it.owner) }) ||
|
||||
function.isCompileTimeTypeAlias()
|
||||
@@ -38,7 +38,7 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
|
||||
private fun IrDeclaration?.isCompileTimeProperty(): Boolean {
|
||||
val property = (this as? IrSimpleFunction)?.correspondingPropertySymbol?.owner ?: return false
|
||||
if (property.isConst) return true
|
||||
if (property.isMarkedWith(compileTimeAnnotation) || property.isCompileTimeTypeAlias()) return true
|
||||
if (property.isMarkedAsCompileTime() || property.isCompileTimeTypeAlias()) return true
|
||||
|
||||
val backingField = property.backingField
|
||||
val backingFieldExpression = backingField?.initializer?.expression as? IrGetValue
|
||||
@@ -73,6 +73,7 @@ enum class EvaluationMode(protected val mustCheckBody: Boolean) {
|
||||
"java.lang.StringBuilder", "java.lang.IllegalArgumentException", "java.util.NoSuchElementException"
|
||||
)
|
||||
|
||||
fun IrDeclaration.isMarkedAsCompileTime() = isMarkedWith(compileTimeAnnotation)
|
||||
private fun IrDeclaration.isContract() = isMarkedWith(contractsDslAnnotation)
|
||||
private fun IrDeclaration.isMarkedAsEvaluateIntrinsic() = isMarkedWith(evaluateIntrinsicAnnotation)
|
||||
protected fun IrDeclaration.isCompileTimeTypeAlias() = this.parentClassOrNull?.fqNameWhenAvailable?.asString() in compileTimeTypeAliases
|
||||
|
||||
+4
@@ -259,4 +259,8 @@ class IrCompileTimeChecker(
|
||||
override fun visitPropertyReference(expression: IrPropertyReference, data: Nothing?): Boolean {
|
||||
return mode.canEvaluateFunction(expression.getter!!.owner)
|
||||
}
|
||||
|
||||
override fun visitClassReference(expression: IrClassReference, data: Nothing?): Boolean {
|
||||
return with(mode) { (expression.symbol.owner as IrClass).isMarkedAsCompileTime() }
|
||||
}
|
||||
}
|
||||
+12
-15
@@ -6,7 +6,6 @@
|
||||
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.types.IrType
|
||||
@@ -19,25 +18,22 @@ internal abstract class AbstractKPropertyProxy(
|
||||
) : ReflectionProxy, KProperty<Any?> {
|
||||
|
||||
protected val propertyType: IrType
|
||||
get() = state.propertyReference.getter!!.owner.returnType
|
||||
|
||||
private val propertyOwner: IrProperty
|
||||
get() = state.propertyReference.symbol.owner
|
||||
get() = state.property.getter!!.returnType
|
||||
|
||||
override val isAbstract: Boolean
|
||||
get() = propertyOwner.modality == Modality.ABSTRACT
|
||||
get() = state.property.modality == Modality.ABSTRACT
|
||||
override val isConst: Boolean
|
||||
get() = propertyOwner.isConst
|
||||
get() = state.property.isConst
|
||||
override val isFinal: Boolean
|
||||
get() = propertyOwner.modality == Modality.FINAL
|
||||
get() = state.property.modality == Modality.FINAL
|
||||
override val isLateinit: Boolean
|
||||
get() = propertyOwner.isLateinit
|
||||
get() = state.property.isLateinit
|
||||
override val isOpen: Boolean
|
||||
get() = propertyOwner.modality == Modality.OPEN
|
||||
get() = state.property.modality == Modality.OPEN
|
||||
override val isSuspend: Boolean
|
||||
get() = TODO("Not yet implemented")
|
||||
get() = false
|
||||
override val name: String
|
||||
get() = propertyOwner.name.asString()
|
||||
get() = state.property.name.asString()
|
||||
|
||||
override val annotations: List<Annotation>
|
||||
get() = TODO("Not yet implemented")
|
||||
@@ -47,14 +43,15 @@ internal abstract class AbstractKPropertyProxy(
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
TODO("Not yet implemented")
|
||||
if (other !is AbstractKPropertyProxy) return false
|
||||
return state == other.state
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
TODO("Not yet implemented")
|
||||
return state.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
TODO("Not yet implemented")
|
||||
return state.toString()
|
||||
}
|
||||
}
|
||||
+77
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* 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.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.internalName
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KClassState
|
||||
import kotlin.reflect.*
|
||||
|
||||
internal class KClassProxy(
|
||||
override val state: KClassState, override val interpreter: IrInterpreter
|
||||
) : ReflectionProxy, KClass<Proxy> {
|
||||
override val simpleName: String?
|
||||
get() = state.irClass.name.asString() // TODO return null if class has no name
|
||||
override val qualifiedName: String?
|
||||
get() = state.irClass.internalName()
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override val constructors: Collection<KFunction<Proxy>>
|
||||
get() = state.getConstructors(interpreter) as Collection<KFunction<Proxy>>
|
||||
override val members: Collection<KCallable<*>>
|
||||
get() = state.getMembers(interpreter)
|
||||
override val nestedClasses: Collection<KClass<*>>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val objectInstance: Proxy?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val typeParameters: List<KTypeParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val supertypes: List<KType>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val sealedSubclasses: List<KClass<out Proxy>>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val annotations: List<Annotation>
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override val visibility: KVisibility?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val isFinal: Boolean
|
||||
get() = state.irClass.modality == Modality.FINAL
|
||||
override val isOpen: Boolean
|
||||
get() = state.irClass.modality == Modality.OPEN
|
||||
override val isAbstract: Boolean
|
||||
get() = state.irClass.modality == Modality.ABSTRACT
|
||||
override val isSealed: Boolean
|
||||
get() = state.irClass.modality == Modality.SEALED
|
||||
override val isData: Boolean
|
||||
get() = state.irClass.isData
|
||||
override val isInner: Boolean
|
||||
get() = state.irClass.isInner
|
||||
override val isCompanion: Boolean
|
||||
get() = state.irClass.isCompanion
|
||||
override val isFun: Boolean
|
||||
get() = state.irClass.isFun
|
||||
override val isValue: Boolean
|
||||
get() = state.irClass.isInline
|
||||
|
||||
override fun isInstance(value: Any?): Boolean {
|
||||
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")
|
||||
}
|
||||
}
|
||||
+33
-31
@@ -20,50 +20,26 @@ internal class KFunctionProxy(
|
||||
) : ReflectionProxy, KFunction<Any?>, FunctionWithAllInvokes {
|
||||
override val arity: Int = state.getArity() ?: BuiltInFunctionArity.BIG_ARITY
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is ReflectionProxy) return false
|
||||
|
||||
return state == other.state
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return state.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return state.toString()
|
||||
}
|
||||
|
||||
override val annotations: List<Annotation>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val isAbstract: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.ABSTRACT
|
||||
override val isExternal: Boolean
|
||||
get() = state.irFunction.isExternal
|
||||
override val isFinal: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.FINAL
|
||||
override val isInfix: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.isInfix
|
||||
override val isInline: Boolean
|
||||
get() = state.irFunction.isInline
|
||||
override val isOpen: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.OPEN
|
||||
override val isExternal: Boolean
|
||||
get() = state.irFunction.isExternal
|
||||
override val isOperator: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.isOperator
|
||||
override val isSuspend: Boolean
|
||||
get() = state.irFunction.isSuspend
|
||||
override val isInfix: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.isInfix
|
||||
override val name: String
|
||||
get() = state.irFunction.name.asString()
|
||||
|
||||
|
||||
override val annotations: List<Annotation>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val parameters: List<KParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val returnType: KType
|
||||
get() = TODO("Not yet implemented")
|
||||
override val typeParameters: List<KTypeParameter>
|
||||
get() = TODO("Not yet implemented")
|
||||
override val visibility: KVisibility?
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun call(vararg args: Any?): Any? {
|
||||
var index = 0
|
||||
@@ -77,5 +53,31 @@ internal class KFunctionProxy(
|
||||
override fun callBy(args: Map<KParameter, Any?>): Any? {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override val visibility: KVisibility?
|
||||
get() = TODO("Not yet implemented")
|
||||
override val isFinal: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.FINAL
|
||||
override val isOpen: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.OPEN
|
||||
override val isAbstract: Boolean
|
||||
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.ABSTRACT
|
||||
override val isSuspend: Boolean
|
||||
get() = state.irFunction.isSuspend
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is ReflectionProxy) return false
|
||||
|
||||
return state == other.state
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return state.hashCode()
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return state.toString()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -35,7 +35,7 @@ internal open class KProperty0Proxy(
|
||||
}
|
||||
|
||||
override fun get(): Any? {
|
||||
return state.dispatchReceiver!!.getState(state.propertyReference.symbol)!!
|
||||
return state.dispatchReceiver!!.getState(state.property.symbol)!!
|
||||
}
|
||||
|
||||
override fun getDelegate(): Any? {
|
||||
@@ -53,6 +53,6 @@ internal class KMutableProperty0Proxy(
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun set(value: Any?) {
|
||||
state.dispatchReceiver!!.setField(Variable(state.propertyReference.symbol, value.toState(propertyType)))
|
||||
state.dispatchReceiver!!.setField(Variable(state.property.symbol, value.toState(propertyType)))
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -36,7 +36,7 @@ internal open class KProperty1Proxy(
|
||||
}
|
||||
|
||||
override fun get(receiver: Proxy): Any? {
|
||||
return receiver.state.getState(state.propertyReference.symbol)!!.wrap(interpreter)
|
||||
return receiver.state.getState(state.property.symbol)!!.wrap(interpreter)
|
||||
}
|
||||
|
||||
override fun getDelegate(receiver: Proxy): Any? {
|
||||
@@ -54,6 +54,6 @@ internal class KMutableProperty1Proxy(
|
||||
get() = TODO("Not yet implemented")
|
||||
|
||||
override fun set(receiver: Proxy, value: Any?) {
|
||||
receiver.state.setField(Variable(state.propertyReference.symbol, value.toState(propertyType)))
|
||||
receiver.state.setField(Variable(state.property.symbol, value.toState(propertyType)))
|
||||
}
|
||||
}
|
||||
+5
-3
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KClassState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||
import org.jetbrains.kotlin.ir.interpreter.state.ReflectionState
|
||||
@@ -16,15 +17,16 @@ internal interface ReflectionProxy : Proxy {
|
||||
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.isKProperty0() -> KProperty0Proxy(this, interpreter)
|
||||
this.isKMutableProperty1() -> KMutableProperty1Proxy(this, interpreter)
|
||||
this.isKProperty2() -> KProperty2Proxy(this, interpreter)
|
||||
this.isKProperty1() -> KProperty1Proxy(this, interpreter)
|
||||
this.isKMutableProperty2() -> KMutableProperty2Proxy(this, interpreter)
|
||||
this.isKProperty2() -> KProperty2Proxy(this, interpreter)
|
||||
else -> TODO()
|
||||
}
|
||||
is KFunctionState -> KFunctionProxy(this, interpreter)
|
||||
is KClassState -> KClassProxy(this, interpreter)
|
||||
else -> TODO("not supported reference state")
|
||||
}
|
||||
}
|
||||
|
||||
+110
-20
@@ -5,67 +5,146 @@
|
||||
|
||||
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.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrClassReference
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
||||
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.getLastOverridden
|
||||
import org.jetbrains.kotlin.ir.interpreter.isFunction
|
||||
import org.jetbrains.kotlin.ir.interpreter.isKFunction
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KFunctionProxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KProperty1Proxy
|
||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.nameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||
import kotlin.reflect.KCallable
|
||||
import kotlin.reflect.KFunction
|
||||
|
||||
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
|
||||
|
||||
protected fun renderReceivers(dispatchReceiver: IrType?, extensionReceiver: IrType?): String {
|
||||
return buildString {
|
||||
if (dispatchReceiver != null) {
|
||||
append(dispatchReceiver.render())
|
||||
append(".")
|
||||
}
|
||||
val addParentheses = dispatchReceiver != null && extensionReceiver != null
|
||||
if (addParentheses) append("(")
|
||||
if (extensionReceiver != null) {
|
||||
append(extensionReceiver.render())
|
||||
append(".")
|
||||
}
|
||||
if (addParentheses) append(")")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal class KClassState(override val irClass: IrClass) : ReflectionState(irClass) {
|
||||
private var _members: Collection<KCallable<*>>? = null
|
||||
private var _constructors: Collection<KFunction<Proxy>>? = null
|
||||
|
||||
constructor(classReference: IrClassReference) : this(classReference.symbol.owner as IrClass)
|
||||
|
||||
fun getMembers(interpreter: IrInterpreter): Collection<KCallable<*>> {
|
||||
if (_members != null) return _members!!
|
||||
_members = irClass.declarations
|
||||
.filter { it !is IrClass && it !is IrConstructor }
|
||||
.map {
|
||||
when (it) {
|
||||
is IrProperty -> KProperty1Proxy(KPropertyState(it, null, null), interpreter) // TODO KProperty2
|
||||
is IrFunction -> KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter)
|
||||
else -> TODO()
|
||||
}
|
||||
}
|
||||
return _members!!
|
||||
}
|
||||
|
||||
fun getConstructors(interpreter: IrInterpreter): Collection<KFunction<Proxy>> {
|
||||
if (_constructors != null) return _constructors!!
|
||||
_constructors = irClass.declarations
|
||||
.filterIsInstance<IrConstructor>()
|
||||
.map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) as KFunction<Proxy> }
|
||||
return _constructors!!
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State?
|
||||
) : ReflectionState(property.parentAsClass) {
|
||||
constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?)
|
||||
: this(propertyReference.symbol.owner, dispatchReceiver, extensionReceiver)
|
||||
|
||||
fun isKProperty0(): Boolean {
|
||||
return className == "KProperty0"
|
||||
return dispatchReceiver != null && extensionReceiver == null
|
||||
}
|
||||
|
||||
fun isKProperty1(): Boolean {
|
||||
return className == "KProperty1"
|
||||
return dispatchReceiver == null && extensionReceiver == null
|
||||
}
|
||||
|
||||
fun isKProperty2(): Boolean {
|
||||
return className == "KProperty2"
|
||||
return dispatchReceiver != null && extensionReceiver != null
|
||||
}
|
||||
|
||||
fun isKMutableProperty0(): Boolean {
|
||||
return className == "KMutableProperty0"
|
||||
return isKProperty0() && property.isVar
|
||||
}
|
||||
|
||||
fun isKMutableProperty1(): Boolean {
|
||||
return className == "KMutableProperty1"
|
||||
return isKProperty1() && property.isVar
|
||||
}
|
||||
|
||||
fun isKMutableProperty2(): Boolean {
|
||||
return className == "KMutableProperty2"
|
||||
return isKProperty1() && property.isVar
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as KPropertyState
|
||||
|
||||
if (property != other.property) return false
|
||||
if (dispatchReceiver != other.dispatchReceiver) return false
|
||||
if (extensionReceiver != other.extensionReceiver) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = property.hashCode()
|
||||
result = 31 * result + (dispatchReceiver?.hashCode() ?: 0)
|
||||
result = 31 * result + (extensionReceiver?.hashCode() ?: 0)
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
val prefix = if (property.isVar) "var" else "val"
|
||||
val receivers = renderReceivers(property.getter?.dispatchReceiverParameter?.type, property.getter?.extensionReceiverParameter?.type)
|
||||
val returnType = property.getter!!.returnType.render()
|
||||
return "$prefix $receivers${property.name}: $returnType"
|
||||
}
|
||||
}
|
||||
|
||||
internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass) {
|
||||
override val fields: MutableList<Variable> = mutableListOf()
|
||||
override val typeArguments: MutableList<Variable> = mutableListOf()
|
||||
val isKFunction = irClass.defaultType.isKFunction()
|
||||
val isFunction = irClass.defaultType.isFunction()
|
||||
|
||||
constructor(functionReference: IrFunctionReference) : this(functionReference.symbol.owner, functionReference.type.classOrNull!!.owner)
|
||||
constructor(irFunction: IrFunction, functionFactory: IrAbstractFunctionFactory) :
|
||||
this(irFunction, functionFactory.functionN(irFunction.valueParameters.size))
|
||||
|
||||
private val invokeSymbol = irClass.declarations
|
||||
.single { it.nameForIrSerialization.asString() == "invoke" }
|
||||
@@ -80,10 +159,21 @@ internal class KFunctionState(val irFunction: IrFunction, override val irClass:
|
||||
return if (invokeSymbol == expression.symbol) irFunction else null
|
||||
}
|
||||
|
||||
private fun isLambda(): Boolean = irFunction.name.let { it == Name.special("<anonymous>") || it == Name.special("<no name provided>") }
|
||||
|
||||
override fun toString(): String {
|
||||
val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.render()
|
||||
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() }
|
||||
val returnType = irFunction.returnType.render()
|
||||
return ("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it }
|
||||
return if (isLambda()) {
|
||||
val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.render()
|
||||
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() }
|
||||
val returnType = irFunction.returnType.render()
|
||||
("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it }
|
||||
} else {
|
||||
val dispatchReceiver = irFunction.parentAsClass.defaultType // = instanceReceiverParameter
|
||||
val extensionReceiver = irFunction.extensionReceiverParameter?.type
|
||||
val receivers = if (irFunction is IrConstructor) "" else renderReceivers(dispatchReceiver, extensionReceiver)
|
||||
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() }
|
||||
val returnType = irFunction.returnType.render()
|
||||
"fun $receivers${irFunction.name}$arguments: $returnType"
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user