From a4edddaa6e937a4c09d7ea3996f889e0bb936e0d Mon Sep 17 00:00:00 2001 From: Ivan Kylchik Date: Mon, 21 Sep 2020 13:18:40 +0300 Subject: [PATCH] Extract all reflection state classes into separate files --- .../state/reflection/KClassState.kt | 86 ++++++ .../state/reflection/KFunctionState.kt | 73 +++++ .../state/reflection/KParameterState.kt | 13 + .../state/reflection/KPropertyState.kt | 70 +++++ .../state/reflection/KTypeParameterState.kt | 40 +++ .../state/reflection/KTypeState.kt | 59 ++++ .../state/reflection/ReflectionState.kt | 274 +----------------- 7 files changed, 347 insertions(+), 268 deletions(-) create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KClassState.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KParameterState.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeParameterState.kt create mode 100644 compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeState.kt diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KClassState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KClassState.kt new file mode 100644 index 00000000000..0f99fd8bfa0 --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KClassState.kt @@ -0,0 +1,86 @@ +/* + * 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.reflection + +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.expressions.IrClassReference +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.proxy.reflection.KFunctionProxy +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KProperty1Proxy +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy +import kotlin.reflect.KCallable +import kotlin.reflect.KFunction +import kotlin.reflect.KType +import kotlin.reflect.KTypeParameter + +internal class KClassState(override val irClass: IrClass) : ReflectionState(irClass.symbol) { + private var _members: Collection>? = null + private var _constructors: Collection>? = null + private var _typeParameters: List? = null + private var _supertypes: List? = null + + constructor(classReference: IrClassReference) : this(classReference.symbol.owner as IrClass) + + fun getMembers(interpreter: IrInterpreter): Collection> { + 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> { + if (_constructors != null) return _constructors!! + _constructors = irClass.declarations + .filterIsInstance() + .map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) } + return _constructors!! + } + + fun getTypeParameters(interpreter: IrInterpreter): List { + if (_typeParameters != null) return _typeParameters!! + _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) } + return _typeParameters!! + } + + fun getSupertypes(interpreter: IrInterpreter): List { + if (_supertypes != null) return _supertypes!! + _supertypes = (irClass.superTypes.map { it } + interpreter.irBuiltIns.anyType).toSet() + .map { KTypeProxy(KTypeState(it), interpreter) } + return _supertypes!! + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KClassState + + if (irClass != other.irClass) return false + + return true + } + + override fun hashCode(): Int { + return irClass.hashCode() + } + + override fun toString(): String { + return "class ${irClass.internalName()}" + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..58253b83490 --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KFunctionState.kt @@ -0,0 +1,73 @@ +/* + * 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.reflection + +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrConstructor +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction +import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory +import org.jetbrains.kotlin.ir.expressions.IrCall +import org.jetbrains.kotlin.ir.expressions.IrFunctionReference +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.getLastOverridden +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy +import org.jetbrains.kotlin.ir.interpreter.renderType +import org.jetbrains.kotlin.ir.interpreter.stack.Variable +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.name.Name +import org.jetbrains.kotlin.utils.addToStdlib.cast +import kotlin.reflect.KTypeParameter + +internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass.symbol) { + override val fields: MutableList = mutableListOf() + override val typeArguments: MutableList = mutableListOf() + private var _typeParameters: List? = null + + constructor(functionReference: IrFunctionReference) : this(functionReference.symbol.owner, functionReference.type.classOrNull!!.owner) + constructor(irFunction: IrFunction, functionFactory: IrAbstractFunctionFactory) : + this(irFunction, functionFactory.kFunctionN(irFunction.valueParameters.size)) + + fun getTypeParameters(interpreter: IrInterpreter): List { + if (_typeParameters != null) return _typeParameters!! + _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) } + return _typeParameters!! + } + + private val invokeSymbol = irClass.declarations + .single { it.nameForIrSerialization.asString() == "invoke" } + .cast() + .getLastOverridden().symbol + + fun getArity(): Int? { + return irClass.name.asString().removePrefix("Function").removePrefix("KFunction").toIntOrNull() + } + + override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? { + return if (invokeSymbol == expression.symbol) irFunction else null + } + + private fun isLambda(): Boolean = irFunction.name.let { it == Name.special("") || it == Name.special("") } + + override fun toString(): String { + return if (isLambda()) { + val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.renderType() + val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() } + val returnType = irFunction.returnType.renderType() + ("$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.renderType() } + val returnType = irFunction.returnType.renderType() + "fun $receivers${irFunction.name}$arguments: $returnType" + } + } +} \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KParameterState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KParameterState.kt new file mode 100644 index 00000000000..ff314e41faa --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KParameterState.kt @@ -0,0 +1,13 @@ +/* + * 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.reflection + +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.classifierOrFail + +internal class KParameterState(val irType: IrType) : ReflectionState(irType.classifierOrFail) { + +} \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt new file mode 100644 index 00000000000..aa07862a16e --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KPropertyState.kt @@ -0,0 +1,70 @@ +/* + * 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.reflection + +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.expressions.IrPropertyReference +import org.jetbrains.kotlin.ir.interpreter.renderType +import org.jetbrains.kotlin.ir.interpreter.state.State +import org.jetbrains.kotlin.ir.util.parentAsClass + +internal class KPropertyState( + val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State? +) : ReflectionState(property.parentAsClass.symbol) { + constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?) + : this(propertyReference.symbol.owner, dispatchReceiver, extensionReceiver) + + fun isKProperty0(): Boolean { + return dispatchReceiver != null && extensionReceiver == null + } + + fun isKProperty1(): Boolean { + return dispatchReceiver == null && extensionReceiver == null + } + + fun isKProperty2(): Boolean { + return dispatchReceiver != null && extensionReceiver != null + } + + fun isKMutableProperty0(): Boolean { + return isKProperty0() && property.isVar + } + + fun isKMutableProperty1(): Boolean { + return isKProperty1() && property.isVar + } + + fun isKMutableProperty2(): Boolean { + 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.renderType() + return "$prefix $receivers${property.name}: $returnType" + } +} \ No newline at end of file diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeParameterState.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeParameterState.kt new file mode 100644 index 00000000000..6b45cecc42c --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeParameterState.kt @@ -0,0 +1,40 @@ +/* + * 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.reflection + +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy +import kotlin.reflect.KType + +internal class KTypeParameterState(val irTypeParameter: IrTypeParameter) : ReflectionState(irTypeParameter) { + private var _upperBounds: List? = null + + fun getUpperBounds(interpreter: IrInterpreter): List { + if (_upperBounds != null) return _upperBounds!! + _upperBounds = irTypeParameter.superTypes.map { KTypeProxy(KTypeState(it), interpreter) } + return _upperBounds!! + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KTypeParameterState + + if (irTypeParameter != other.irTypeParameter) return false + + return true + } + + override fun hashCode(): Int { + return irTypeParameter.hashCode() + } + + override fun toString(): String { + return irTypeParameter.name.asString() + } +} \ No newline at end of file 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 new file mode 100644 index 00000000000..b8c9cda6abf --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/state/reflection/KTypeState.kt @@ -0,0 +1,59 @@ +/* + * 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.reflection + +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy +import org.jetbrains.kotlin.ir.interpreter.renderType +import org.jetbrains.kotlin.ir.types.* +import org.jetbrains.kotlin.types.Variance +import kotlin.reflect.KTypeProjection + +internal class KTypeState(val irType: IrType) : ReflectionState(irType.classifierOrFail) { + private var _arguments: List? = null + + fun getArguments(interpreter: IrInterpreter): List { + if (_arguments != null) return _arguments!! + _arguments = (irType as IrSimpleType).arguments + .map { + when (it.getVariance()) { + Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) + Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) + Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) + null -> KTypeProjection.STAR + } + } + return _arguments!! + } + + private fun IrTypeArgument.getVariance(): Variance? { + return when (this) { + is IrSimpleType -> Variance.INVARIANT + is IrTypeProjection -> this.variance + is IrStarProjection -> null + else -> TODO() + } + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KTypeState + + if (irType != other.irType) return false + + return true + } + + override fun hashCode(): Int { + return irType.hashCode() + } + + override fun toString(): String { + return irType.renderType() + } +} \ No newline at end of file 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 0e8ab7f5a40..3b5e5ddab15 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 @@ -5,33 +5,18 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection -import org.jetbrains.kotlin.ir.declarations.* -import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter 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.internalName -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.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.stack.Variable import org.jetbrains.kotlin.ir.interpreter.state.State import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol -import org.jetbrains.kotlin.ir.types.* -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.name.Name -import org.jetbrains.kotlin.types.Variance -import org.jetbrains.kotlin.utils.addToStdlib.cast +import org.jetbrains.kotlin.ir.types.IrType +import org.jetbrains.kotlin.ir.types.classOrNull +import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult -import kotlin.reflect.* internal abstract class ReflectionState(val irClassifierSymbol: IrClassifierSymbol) : State { override val irClass: IrClass = irClassifierSymbol.extractClass() @@ -69,250 +54,3 @@ internal abstract class ReflectionState(val irClassifierSymbol: IrClassifierSymb } } } - -internal class KClassState(override val irClass: IrClass) : ReflectionState(irClass.symbol) { - private var _members: Collection>? = null - private var _constructors: Collection>? = null - private var _typeParameters: List? = null - private var _supertypes: List? = null - - constructor(classReference: IrClassReference) : this(classReference.symbol.owner as IrClass) - - fun getMembers(interpreter: IrInterpreter): Collection> { - 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> { - if (_constructors != null) return _constructors!! - _constructors = irClass.declarations - .filterIsInstance() - .map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) as KFunction } - return _constructors!! - } - - fun getTypeParameters(interpreter: IrInterpreter): List { - if (_typeParameters != null) return _typeParameters!! - _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) } - return _typeParameters!! - } - - fun getSupertypes(interpreter: IrInterpreter): List { - if (_supertypes != null) return _supertypes!! - _supertypes = (irClass.superTypes.map { it } + interpreter.irBuiltIns.anyType).toSet() - .map { KTypeProxy(KTypeState(it), interpreter) } - return _supertypes!! - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as KClassState - - if (irClass != other.irClass) return false - - return true - } - - override fun hashCode(): Int { - return irClass.hashCode() - } - - override fun toString(): String { - return "class ${irClass.internalName()}" - } -} - -internal class KPropertyState( - val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State? -) : ReflectionState(property.parentAsClass.symbol) { - constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?) - : this(propertyReference.symbol.owner, dispatchReceiver, extensionReceiver) - - fun isKProperty0(): Boolean { - return dispatchReceiver != null && extensionReceiver == null - } - - fun isKProperty1(): Boolean { - return dispatchReceiver == null && extensionReceiver == null - } - - fun isKProperty2(): Boolean { - return dispatchReceiver != null && extensionReceiver != null - } - - fun isKMutableProperty0(): Boolean { - return isKProperty0() && property.isVar - } - - fun isKMutableProperty1(): Boolean { - return isKProperty1() && property.isVar - } - - fun isKMutableProperty2(): Boolean { - 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.renderType() - return "$prefix $receivers${property.name}: $returnType" - } -} - -internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass.symbol) { - override val fields: MutableList = mutableListOf() - override val typeArguments: MutableList = mutableListOf() - private var _typeParameters: List? = null - - constructor(functionReference: IrFunctionReference) : this(functionReference.symbol.owner, functionReference.type.classOrNull!!.owner) - constructor(irFunction: IrFunction, functionFactory: IrAbstractFunctionFactory) : - this(irFunction, functionFactory.kFunctionN(irFunction.valueParameters.size)) - - fun getTypeParameters(interpreter: IrInterpreter): List { - if (_typeParameters != null) return _typeParameters!! - _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) } - return _typeParameters!! - } - - private val invokeSymbol = irClass.declarations - .single { it.nameForIrSerialization.asString() == "invoke" } - .cast() - .getLastOverridden().symbol - - fun getArity(): Int? { - return irClass.name.asString().removePrefix("Function").removePrefix("KFunction").toIntOrNull() - } - - override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? { - return if (invokeSymbol == expression.symbol) irFunction else null - } - - private fun isLambda(): Boolean = irFunction.name.let { it == Name.special("") || it == Name.special("") } - - override fun toString(): String { - return if (isLambda()) { - val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.renderType() - val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() } - val returnType = irFunction.returnType.renderType() - ("$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.renderType() } - val returnType = irFunction.returnType.renderType() - "fun $receivers${irFunction.name}$arguments: $returnType" - } - } -} - -internal class KTypeState(val irType: IrType) : ReflectionState(irType.classifierOrFail) { - private var _arguments: List? = null - - fun getArguments(interpreter: IrInterpreter): List { - if (_arguments != null) return _arguments!! - _arguments = (irType as IrSimpleType).arguments - .map { - when (it.getVariance()) { - Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) - Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) - Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) - null -> KTypeProjection.STAR - } - } - return _arguments!! - } - - private fun IrTypeArgument.getVariance(): Variance? { - return when (this) { - is IrSimpleType -> Variance.INVARIANT - is IrTypeProjection -> this.variance - is IrStarProjection -> null - else -> TODO() - } - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as KTypeState - - if (irType != other.irType) return false - - return true - } - - override fun hashCode(): Int { - return irType.hashCode() - } - - override fun toString(): String { - return irType.renderType() - } -} - -internal class KTypeParameterState(val irTypeParameter: IrTypeParameter) : ReflectionState(irTypeParameter) { - private var _upperBounds: List? = null - - fun getUpperBounds(interpreter: IrInterpreter): List { - if (_upperBounds != null) return _upperBounds!! - _upperBounds = irTypeParameter.superTypes.map { KTypeProxy(KTypeState(it), interpreter) } - return _upperBounds!! - } - - override fun equals(other: Any?): Boolean { - if (this === other) return true - if (javaClass != other?.javaClass) return false - - other as KTypeParameterState - - if (irTypeParameter != other.irTypeParameter) return false - - return true - } - - override fun hashCode(): Int { - return irTypeParameter.hashCode() - } - - override fun toString(): String { - return irTypeParameter.name.asString() - } -} - -internal class KParameterState(val irType: IrType) : ReflectionState(irType.classifierOrFail) { - -} \ No newline at end of file