diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt index b37d23e0e5d..3c041183341 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/AbstractKPropertyProxy.kt @@ -8,7 +8,6 @@ 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.state.reflection.KPropertyState -import org.jetbrains.kotlin.ir.interpreter.state.reflection.KTypeState import org.jetbrains.kotlin.ir.types.IrType import kotlin.reflect.KProperty import kotlin.reflect.KType @@ -39,9 +38,9 @@ internal abstract class AbstractKPropertyProxy( override val annotations: List get() = TODO("Not yet implemented") override val returnType: KType - get() = KTypeProxy(KTypeState(propertyType), interpreter) + get() = state.getReturnType(interpreter) override val visibility: KVisibility? - get() = state.irClass.visibility.toKVisibility() + get() = state.property.visibility.toKVisibility() override fun equals(other: Any?): Boolean { if (other !is AbstractKPropertyProxy) return false diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KClassProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KClassProxy.kt index e75b71155cb..09aa34f5c3e 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KClassProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KClassProxy.kt @@ -16,9 +16,9 @@ internal class KClassProxy( override val state: KClassState, override val interpreter: IrInterpreter ) : ReflectionProxy, KClass { override val simpleName: String? - get() = state.irClass.name.takeIf { !it.isSpecial }?.asString() + get() = state.classReference.name.takeIf { !it.isSpecial }?.asString() override val qualifiedName: String? - get() = if (!state.irClass.name.isSpecial) state.irClass.internalName() else null + get() = if (!state.classReference.name.isSpecial) state.classReference.internalName() else null @Suppress("UNCHECKED_CAST") override val constructors: Collection> @@ -39,25 +39,25 @@ internal class KClassProxy( get() = TODO("Not yet implemented") override val visibility: KVisibility? - get() = state.irClass.visibility.toKVisibility() + get() = state.classReference.visibility.toKVisibility() override val isFinal: Boolean - get() = state.irClass.modality == Modality.FINAL + get() = state.classReference.modality == Modality.FINAL override val isOpen: Boolean - get() = state.irClass.modality == Modality.OPEN + get() = state.classReference.modality == Modality.OPEN override val isAbstract: Boolean - get() = state.irClass.modality == Modality.ABSTRACT + get() = state.classReference.modality == Modality.ABSTRACT override val isSealed: Boolean - get() = state.irClass.modality == Modality.SEALED + get() = state.classReference.modality == Modality.SEALED override val isData: Boolean - get() = state.irClass.isData + get() = state.classReference.isData override val isInner: Boolean - get() = state.irClass.isInner + get() = state.classReference.isInner override val isCompanion: Boolean - get() = state.irClass.isCompanion + get() = state.classReference.isCompanion override val isFun: Boolean - get() = state.irClass.isFun + get() = state.classReference.isFun override val isValue: Boolean - get() = state.irClass.isInline + get() = state.classReference.isInline override fun isInstance(value: Any?): Boolean { TODO("Not yet implemented") diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt index 4a7801a97c2..fddee37ea44 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KFunctionProxy.kt @@ -36,9 +36,9 @@ internal class KFunctionProxy( override val annotations: List get() = TODO("Not yet implemented") override val parameters: List - get() = TODO("Not yet implemented") + get() = state.getParameters(interpreter) override val returnType: KType - get() = KTypeProxy(KTypeState(state.irFunction.returnType), interpreter) + get() = state.getReturnType(interpreter) override val typeParameters: List get() = state.getTypeParameters(interpreter) @@ -56,7 +56,7 @@ internal class KFunctionProxy( } override val visibility: KVisibility? - get() = state.irClass.visibility.toKVisibility() + get() = state.irFunction.visibility.toKVisibility() override val isFinal: Boolean get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.FINAL override val isOpen: Boolean diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KParameterProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KParameterProxy.kt new file mode 100644 index 00000000000..a877a980203 --- /dev/null +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KParameterProxy.kt @@ -0,0 +1,39 @@ +/* + * 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.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.state.reflection.KParameterState +import kotlin.reflect.KParameter +import kotlin.reflect.KType + +internal class KParameterProxy(override val state: KParameterState, override val interpreter: IrInterpreter) : ReflectionProxy, KParameter { + override val index: Int + get() = state.index + override val name: String? + get() = if (kind == KParameter.Kind.VALUE) state.irParameter.name.asString() else null + override val type: KType + get() = state.getType(interpreter) + override val kind: KParameter.Kind + get() = state.kind + override val isOptional: Boolean + get() = state.irParameter.defaultValue != null + override val isVararg: Boolean + get() = state.irParameter.varargElementType != null + override val annotations: List + get() = TODO("Not yet implemented") + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other !is KParameterProxy) return false + + return state == other.state + } + + override fun hashCode(): Int = state.hashCode() + + override fun toString(): String = state.toString() +} diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KTypeProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KTypeProxy.kt index ff64b69cc40..17e10acac25 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KTypeProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/KTypeProxy.kt @@ -19,11 +19,7 @@ import kotlin.reflect.KTypeProjection internal class KTypeProxy(override val state: KTypeState, override val interpreter: IrInterpreter) : ReflectionProxy, KType { override val classifier: KClassifier? - get() = when (val classifier = state.irType.classifierOrFail.owner) { - is IrClass -> KClassProxy(KClassState(classifier), interpreter) - is IrTypeParameter -> KTypeParameterProxy(KTypeParameterState(classifier), interpreter) - else -> TODO() - } + get() = state.getClassifier(interpreter) override val arguments: List get() = state.getArguments(interpreter) override val isMarkedNullable: Boolean diff --git a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt index 6daecd57218..1307a688e3d 100644 --- a/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/proxy/reflection/ReflectionProxy.kt @@ -39,6 +39,7 @@ internal interface ReflectionProxy : Proxy { is KClassState -> KClassProxy(this, interpreter) is KTypeState -> KTypeProxy(this, interpreter) is KTypeParameterState -> KTypeParameterProxy(this, interpreter) + is KParameterState -> KParameterProxy(this, interpreter) else -> TODO("not supported reference state") } } 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 index 0f99fd8bfa0..9b1eb7e6ff5 100644 --- 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 @@ -13,30 +13,45 @@ 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 org.jetbrains.kotlin.ir.interpreter.proxy.reflection.* +import org.jetbrains.kotlin.ir.types.classOrNull 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) { +internal class KClassState(val classReference: IrClass, override val irClass: IrClass) : ReflectionState() { 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) + constructor(classReference: IrClassReference) : this(classReference.symbol.owner as IrClass, classReference.type.classOrNull!!.owner) fun getMembers(interpreter: IrInterpreter): Collection> { if (_members != null) return _members!! - _members = irClass.declarations + _members = classReference.declarations .filter { it !is IrClass && it !is IrConstructor } .map { when (it) { - is IrProperty -> KProperty1Proxy(KPropertyState(it, null, null), interpreter) // TODO KProperty2 + is IrProperty -> { + val withExtension = it.getter?.extensionReceiverParameter != null + when { + !withExtension && !it.isVar -> + KProperty1Proxy(KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(false, 1).owner), interpreter) + !withExtension && it.isVar -> + KMutableProperty1Proxy( + KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(true, 1).owner), interpreter + ) + withExtension && !it.isVar -> + KProperty2Proxy(KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(false, 2).owner), interpreter) + !withExtension && it.isVar -> + KMutableProperty2Proxy( + KPropertyState(it, interpreter.irBuiltIns.getKPropertyClass(true, 2).owner), interpreter + ) + else -> TODO() + } + } is IrFunction -> KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) else -> TODO() } @@ -46,7 +61,7 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl fun getConstructors(interpreter: IrInterpreter): Collection> { if (_constructors != null) return _constructors!! - _constructors = irClass.declarations + _constructors = classReference.declarations .filterIsInstance() .map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) } return _constructors!! @@ -54,14 +69,16 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl fun getTypeParameters(interpreter: IrInterpreter): List { if (_typeParameters != null) return _typeParameters!! - _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) } + val kTypeParameterIrClass = irClass.getIrClassOfReflectionFromList("typeParameters") + _typeParameters = classReference.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it, kTypeParameterIrClass), 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) } + val kTypeIrClass = irClass.getIrClassOfReflectionFromList("supertypes") + _supertypes = (classReference.superTypes.map { it } + interpreter.irBuiltIns.anyType).toSet() + .map { KTypeProxy(KTypeState(it, kTypeIrClass), interpreter) } return _supertypes!! } @@ -71,16 +88,16 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl other as KClassState - if (irClass != other.irClass) return false + if (classReference != other.classReference) return false return true } override fun hashCode(): Int { - return irClass.hashCode() + return classReference.hashCode() } override fun toString(): String { - return "class ${irClass.internalName()}" + return "class ${classReference.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 index 58253b83490..3dd7ef51e9b 100644 --- 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 @@ -6,7 +6,6 @@ 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 @@ -14,29 +13,53 @@ 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.KParameterProxy import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeParameterProxy -import org.jetbrains.kotlin.ir.interpreter.renderType +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy 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.KParameter +import kotlin.reflect.KType import kotlin.reflect.KTypeParameter -internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass.symbol) { +internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState() { override val fields: MutableList = mutableListOf() override val typeArguments: MutableList = mutableListOf() + private var _parameters: List? = null + private var _returnType: KType? = null 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 getParameters(interpreter: IrInterpreter): List { + if (_parameters != null) return _parameters!! + val kParameterIrClass = irClass.getIrClassOfReflectionFromList("parameters") + var index = 0 + val instanceParameter = irFunction.dispatchReceiverParameter + ?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.INSTANCE), interpreter) } + val extensionParameter = irFunction.extensionReceiverParameter + ?.let { KParameterProxy(KParameterState(kParameterIrClass, it, index++, KParameter.Kind.EXTENSION_RECEIVER), interpreter) } + _parameters = listOfNotNull(instanceParameter, extensionParameter) + + irFunction.valueParameters.map { KParameterProxy(KParameterState(kParameterIrClass, it, index++), interpreter) } + return _parameters!! + } + + fun getReturnType(interpreter: IrInterpreter): KType { + if (_returnType != null) return _returnType!! + val kTypeIrClass = irClass.getIrClassOfReflection("returnType") + _returnType = KTypeProxy(KTypeState(irFunction.returnType, kTypeIrClass), interpreter) + return _returnType!! + } + fun getTypeParameters(interpreter: IrInterpreter): List { if (_typeParameters != null) return _typeParameters!! - _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) } + val kTypeParametersIrClass = irClass.getIrClassOfReflectionFromList("typeParameters") + _typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it, kTypeParametersIrClass), interpreter) } return _typeParameters!! } @@ -56,18 +79,6 @@ internal class KFunctionState(val irFunction: IrFunction, override val irClass: 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" - } + return if (isLambda()) renderLambda(irFunction) else renderFunction(irFunction) } } \ 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 index ff314e41faa..333ee6cf5be 100644 --- 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 @@ -5,9 +5,56 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection -import org.jetbrains.kotlin.ir.types.IrType -import org.jetbrains.kotlin.ir.types.classifierOrFail +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.declarations.IrProperty +import org.jetbrains.kotlin.ir.declarations.IrValueParameter +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy +import kotlin.reflect.KParameter +import kotlin.reflect.KType -internal class KParameterState(val irType: IrType) : ReflectionState(irType.classifierOrFail) { +internal class KParameterState( + override val irClass: IrClass, val irParameter: IrValueParameter, val index: Int, val kind: KParameter.Kind = KParameter.Kind.VALUE +) : ReflectionState() { + private var _type: KType? = null + fun getType(interpreter: IrInterpreter): KType { + if (_type != null) return _type!! + val kTypeIrClass = irClass.getIrClassOfReflection("type") + _type = KTypeProxy(KTypeState(irParameter.type, kTypeIrClass), interpreter) + return _type!! + } + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (javaClass != other?.javaClass) return false + + other as KParameterState + + if (irParameter != other.irParameter) return false + + return true + } + + override fun hashCode(): Int { + return irParameter.hashCode() + } + + override fun toString(): String { + return buildString { + when (kind) { + KParameter.Kind.EXTENSION_RECEIVER -> append("extension receiver parameter") + KParameter.Kind.INSTANCE -> append("instance parameter") + KParameter.Kind.VALUE -> append("parameter #$index ${irParameter.name}") + } + + append(" of ") + when (val parent = irParameter.parent) { + is IrFunction -> append(renderFunction(parent)) + is IrProperty -> append(renderProperty(parent)) + else -> TODO() + } + } + } } \ 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 index aa07862a16e..991a80d1092 100644 --- 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 @@ -5,41 +5,42 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection +import org.jetbrains.kotlin.ir.declarations.IrClass 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.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy import org.jetbrains.kotlin.ir.interpreter.state.State -import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.types.classOrNull +import kotlin.reflect.KType internal class KPropertyState( - val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State? -) : ReflectionState(property.parentAsClass.symbol) { + val property: IrProperty, override val irClass: IrClass, val dispatchReceiver: State? = null, val extensionReceiver: State? = null +) : ReflectionState() { + constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?) - : this(propertyReference.symbol.owner, dispatchReceiver, extensionReceiver) + : this(propertyReference.symbol.owner, propertyReference.type.classOrNull!!.owner, dispatchReceiver, extensionReceiver) - fun isKProperty0(): Boolean { - return dispatchReceiver != null && extensionReceiver == null + private var _returnType: KType? = null + + fun getReturnType(interpreter: IrInterpreter): KType { + if (_returnType != null) return _returnType!! + val kTypeIrClass = irClass.getIrClassOfReflection("returnType") + _returnType = KTypeProxy(KTypeState(property.getter!!.returnType, kTypeIrClass), interpreter) + return _returnType!! } - fun isKProperty1(): Boolean { - return dispatchReceiver == null && extensionReceiver == null - } + fun isKProperty0(): Boolean = irClass.name.asString() == "KProperty0" - fun isKProperty2(): Boolean { - return dispatchReceiver != null && extensionReceiver != null - } + fun isKProperty1(): Boolean = irClass.name.asString() == "KProperty1" - fun isKMutableProperty0(): Boolean { - return isKProperty0() && property.isVar - } + fun isKProperty2(): Boolean = irClass.name.asString() == "KProperty2" - fun isKMutableProperty1(): Boolean { - return isKProperty1() && property.isVar - } + fun isKMutableProperty0(): Boolean = irClass.name.asString() == "KMutableProperty0" - fun isKMutableProperty2(): Boolean { - return isKProperty1() && property.isVar - } + fun isKMutableProperty1(): Boolean = irClass.name.asString() == "KMutableProperty1" + + fun isKMutableProperty2(): Boolean = irClass.name.asString() == "KMutableProperty2" override fun equals(other: Any?): Boolean { if (this === other) return true @@ -62,9 +63,6 @@ internal class KPropertyState( } 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" + return renderProperty(property) } } \ 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 index 6b45cecc42c..a46651d3be6 100644 --- 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 @@ -5,17 +5,19 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection +import org.jetbrains.kotlin.ir.declarations.IrClass 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) { +internal class KTypeParameterState(val irTypeParameter: IrTypeParameter, override val irClass: IrClass) : ReflectionState() { private var _upperBounds: List? = null fun getUpperBounds(interpreter: IrInterpreter): List { if (_upperBounds != null) return _upperBounds!! - _upperBounds = irTypeParameter.superTypes.map { KTypeProxy(KTypeState(it), interpreter) } + val kTypeIrClass = irClass.getIrClassOfReflectionFromList("upperBounds") + _upperBounds = irTypeParameter.superTypes.map { KTypeProxy(KTypeState(it, kTypeIrClass), interpreter) } return _upperBounds!! } 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 index b8c9cda6abf..1196871a937 100644 --- 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 @@ -5,24 +5,43 @@ package org.jetbrains.kotlin.ir.interpreter.state.reflection +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrTypeParameter import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KClassProxy +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.types.* import org.jetbrains.kotlin.types.Variance +import kotlin.reflect.KClassifier import kotlin.reflect.KTypeProjection -internal class KTypeState(val irType: IrType) : ReflectionState(irType.classifierOrFail) { +internal class KTypeState(val irType: IrType, override val irClass: IrClass) : ReflectionState() { + private var _classifier: KClassifier? = null private var _arguments: List? = null + fun getClassifier(interpreter: IrInterpreter): KClassifier? { + if (_classifier != null) return _classifier!! + _classifier = when (val classifier = irType.classifierOrFail.owner) { + is IrClass -> KClassProxy(KClassState(classifier, interpreter.irBuiltIns.kClassClass.owner), interpreter) + is IrTypeParameter -> { + val kTypeParameterIrClass = interpreter.irBuiltIns.kClassClass.owner.getIrClassOfReflectionFromList("typeParameters") + KTypeParameterProxy(KTypeParameterState(classifier, kTypeParameterIrClass), interpreter) + } + else -> TODO() + } + return _classifier!! + } + 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)) + Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter)) + Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter)) + Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter)) null -> KTypeProjection.STAR } } 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 3b5e5ddab15..d6c15d86c65 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 @@ -6,28 +6,40 @@ 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.IrTypeParameter +import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.expressions.IrCall 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.IrSimpleType 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 org.jetbrains.kotlin.ir.types.typeOrNull +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.nameForIrSerialization +import org.jetbrains.kotlin.ir.util.parentClassOrNull -internal abstract class ReflectionState(val irClassifierSymbol: IrClassifierSymbol) : State { - override val irClass: IrClass = irClassifierSymbol.extractClass() +internal abstract class ReflectionState : State { override val fields: MutableList = mutableListOf() override val typeArguments: MutableList = mutableListOf() - constructor(irTypeParameter: IrTypeParameter) : this(irTypeParameter.superTypes.firstNotNullResult { it.classifierOrNull }!!) - override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null - protected fun renderReceivers(dispatchReceiver: IrType?, extensionReceiver: IrType?): String { + protected fun IrClass.getIrClassOfReflectionFromList(name: String): IrClass { + val property = this.declarations.single { it.nameForIrSerialization.asString() == name } as IrProperty + val list = property.getter!!.returnType as IrSimpleType + return list.arguments.single().typeOrNull!!.classOrNull!!.owner + } + + protected fun IrClass.getIrClassOfReflection(name: String): IrClass { + val property = this.declarations.single { it.nameForIrSerialization.asString() == name } as IrProperty + val type = property.getter!!.returnType as IrSimpleType + return type.classOrNull!!.owner + } + + private fun renderReceivers(dispatchReceiver: IrType?, extensionReceiver: IrType?): String { return buildString { if (dispatchReceiver != null) { append(dispatchReceiver.renderType()) @@ -43,14 +55,26 @@ internal abstract class ReflectionState(val irClassifierSymbol: IrClassifierSymb } } - companion object { - private fun IrClassifierSymbol.extractClass(): IrClass { - return (owner as? IrClass) ?: (owner as IrTypeParameter).extractAnyClass() - } + protected fun renderLambda(irFunction: IrFunction): String { + val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.renderType() + val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() } + val returnType = irFunction.returnType.renderType() + return ("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it } + } - private fun IrTypeParameter.extractAnyClass(): IrClass { - return this.superTypes - .firstNotNullResult { it.classOrNull?.owner ?: (it.classifierOrNull?.owner as? IrTypeParameter)?.extractAnyClass() }!! - } + protected fun renderFunction(irFunction: IrFunction): String { + val dispatchReceiver = irFunction.parentClassOrNull?.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() + return "fun $receivers${irFunction.name}$arguments: $returnType" + } + + protected fun renderProperty(property: IrProperty): 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" } }