Implement interpretation of KParameter interface

This commit is contained in:
Ivan Kylchik
2020-09-21 19:17:54 +03:00
committed by TeamCityServer
parent a4edddaa6e
commit f89b75e387
13 changed files with 262 additions and 109 deletions
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.state.reflection.KPropertyState 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 org.jetbrains.kotlin.ir.types.IrType
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
import kotlin.reflect.KType import kotlin.reflect.KType
@@ -39,9 +38,9 @@ internal abstract class AbstractKPropertyProxy(
override val annotations: List<Annotation> override val annotations: List<Annotation>
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val returnType: KType override val returnType: KType
get() = KTypeProxy(KTypeState(propertyType), interpreter) get() = state.getReturnType(interpreter)
override val visibility: KVisibility? override val visibility: KVisibility?
get() = state.irClass.visibility.toKVisibility() get() = state.property.visibility.toKVisibility()
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (other !is AbstractKPropertyProxy) return false if (other !is AbstractKPropertyProxy) return false
@@ -16,9 +16,9 @@ internal class KClassProxy(
override val state: KClassState, override val interpreter: IrInterpreter override val state: KClassState, override val interpreter: IrInterpreter
) : ReflectionProxy, KClass<Proxy> { ) : ReflectionProxy, KClass<Proxy> {
override val simpleName: String? override val simpleName: String?
get() = state.irClass.name.takeIf { !it.isSpecial }?.asString() get() = state.classReference.name.takeIf { !it.isSpecial }?.asString()
override val qualifiedName: String? 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") @Suppress("UNCHECKED_CAST")
override val constructors: Collection<KFunction<Proxy>> override val constructors: Collection<KFunction<Proxy>>
@@ -39,25 +39,25 @@ internal class KClassProxy(
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val visibility: KVisibility? override val visibility: KVisibility?
get() = state.irClass.visibility.toKVisibility() get() = state.classReference.visibility.toKVisibility()
override val isFinal: Boolean override val isFinal: Boolean
get() = state.irClass.modality == Modality.FINAL get() = state.classReference.modality == Modality.FINAL
override val isOpen: Boolean override val isOpen: Boolean
get() = state.irClass.modality == Modality.OPEN get() = state.classReference.modality == Modality.OPEN
override val isAbstract: Boolean override val isAbstract: Boolean
get() = state.irClass.modality == Modality.ABSTRACT get() = state.classReference.modality == Modality.ABSTRACT
override val isSealed: Boolean override val isSealed: Boolean
get() = state.irClass.modality == Modality.SEALED get() = state.classReference.modality == Modality.SEALED
override val isData: Boolean override val isData: Boolean
get() = state.irClass.isData get() = state.classReference.isData
override val isInner: Boolean override val isInner: Boolean
get() = state.irClass.isInner get() = state.classReference.isInner
override val isCompanion: Boolean override val isCompanion: Boolean
get() = state.irClass.isCompanion get() = state.classReference.isCompanion
override val isFun: Boolean override val isFun: Boolean
get() = state.irClass.isFun get() = state.classReference.isFun
override val isValue: Boolean override val isValue: Boolean
get() = state.irClass.isInline get() = state.classReference.isInline
override fun isInstance(value: Any?): Boolean { override fun isInstance(value: Any?): Boolean {
TODO("Not yet implemented") TODO("Not yet implemented")
@@ -36,9 +36,9 @@ internal class KFunctionProxy(
override val annotations: List<Annotation> override val annotations: List<Annotation>
get() = TODO("Not yet implemented") get() = TODO("Not yet implemented")
override val parameters: List<KParameter> override val parameters: List<KParameter>
get() = TODO("Not yet implemented") get() = state.getParameters(interpreter)
override val returnType: KType override val returnType: KType
get() = KTypeProxy(KTypeState(state.irFunction.returnType), interpreter) get() = state.getReturnType(interpreter)
override val typeParameters: List<KTypeParameter> override val typeParameters: List<KTypeParameter>
get() = state.getTypeParameters(interpreter) get() = state.getTypeParameters(interpreter)
@@ -56,7 +56,7 @@ internal class KFunctionProxy(
} }
override val visibility: KVisibility? override val visibility: KVisibility?
get() = state.irClass.visibility.toKVisibility() get() = state.irFunction.visibility.toKVisibility()
override val isFinal: Boolean override val isFinal: Boolean
get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.FINAL get() = state.irFunction is IrSimpleFunction && state.irFunction.modality == Modality.FINAL
override val isOpen: Boolean override val isOpen: Boolean
@@ -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<Annotation>
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()
}
@@ -19,11 +19,7 @@ import kotlin.reflect.KTypeProjection
internal class KTypeProxy(override val state: KTypeState, override val interpreter: IrInterpreter) : ReflectionProxy, KType { internal class KTypeProxy(override val state: KTypeState, override val interpreter: IrInterpreter) : ReflectionProxy, KType {
override val classifier: KClassifier? override val classifier: KClassifier?
get() = when (val classifier = state.irType.classifierOrFail.owner) { get() = state.getClassifier(interpreter)
is IrClass -> KClassProxy(KClassState(classifier), interpreter)
is IrTypeParameter -> KTypeParameterProxy(KTypeParameterState(classifier), interpreter)
else -> TODO()
}
override val arguments: List<KTypeProjection> override val arguments: List<KTypeProjection>
get() = state.getArguments(interpreter) get() = state.getArguments(interpreter)
override val isMarkedNullable: Boolean override val isMarkedNullable: Boolean
@@ -39,6 +39,7 @@ internal interface ReflectionProxy : Proxy {
is KClassState -> KClassProxy(this, interpreter) is KClassState -> KClassProxy(this, interpreter)
is KTypeState -> KTypeProxy(this, interpreter) is KTypeState -> KTypeProxy(this, interpreter)
is KTypeParameterState -> KTypeParameterProxy(this, interpreter) is KTypeParameterState -> KTypeParameterProxy(this, interpreter)
is KParameterState -> KParameterProxy(this, interpreter)
else -> TODO("not supported reference state") else -> TODO("not supported reference state")
} }
} }
@@ -13,30 +13,45 @@ import org.jetbrains.kotlin.ir.expressions.IrClassReference
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.internalName import org.jetbrains.kotlin.ir.interpreter.internalName
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy 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.*
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KProperty1Proxy import org.jetbrains.kotlin.ir.types.classOrNull
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.KCallable
import kotlin.reflect.KFunction import kotlin.reflect.KFunction
import kotlin.reflect.KType import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter 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<KCallable<*>>? = null private var _members: Collection<KCallable<*>>? = null
private var _constructors: Collection<KFunction<*>>? = null private var _constructors: Collection<KFunction<*>>? = null
private var _typeParameters: List<KTypeParameter>? = null private var _typeParameters: List<KTypeParameter>? = null
private var _supertypes: List<KType>? = null private var _supertypes: List<KType>? = 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<KCallable<*>> { fun getMembers(interpreter: IrInterpreter): Collection<KCallable<*>> {
if (_members != null) return _members!! if (_members != null) return _members!!
_members = irClass.declarations _members = classReference.declarations
.filter { it !is IrClass && it !is IrConstructor } .filter { it !is IrClass && it !is IrConstructor }
.map { .map {
when (it) { 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) is IrFunction -> KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter)
else -> TODO() else -> TODO()
} }
@@ -46,7 +61,7 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl
fun getConstructors(interpreter: IrInterpreter): Collection<KFunction<*>> { fun getConstructors(interpreter: IrInterpreter): Collection<KFunction<*>> {
if (_constructors != null) return _constructors!! if (_constructors != null) return _constructors!!
_constructors = irClass.declarations _constructors = classReference.declarations
.filterIsInstance<IrConstructor>() .filterIsInstance<IrConstructor>()
.map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) } .map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) }
return _constructors!! return _constructors!!
@@ -54,14 +69,16 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl
fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> { fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> {
if (_typeParameters != null) return _typeParameters!! 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!! return _typeParameters!!
} }
fun getSupertypes(interpreter: IrInterpreter): List<KType> { fun getSupertypes(interpreter: IrInterpreter): List<KType> {
if (_supertypes != null) return _supertypes!! if (_supertypes != null) return _supertypes!!
_supertypes = (irClass.superTypes.map { it } + interpreter.irBuiltIns.anyType).toSet() val kTypeIrClass = irClass.getIrClassOfReflectionFromList("supertypes")
.map { KTypeProxy(KTypeState(it), interpreter) } _supertypes = (classReference.superTypes.map { it } + interpreter.irBuiltIns.anyType).toSet()
.map { KTypeProxy(KTypeState(it, kTypeIrClass), interpreter) }
return _supertypes!! return _supertypes!!
} }
@@ -71,16 +88,16 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl
other as KClassState other as KClassState
if (irClass != other.irClass) return false if (classReference != other.classReference) return false
return true return true
} }
override fun hashCode(): Int { override fun hashCode(): Int {
return irClass.hashCode() return classReference.hashCode()
} }
override fun toString(): String { override fun toString(): String {
return "class ${irClass.internalName()}" return "class ${classReference.internalName()}"
} }
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.IrClass 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.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory 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.expressions.IrFunctionReference
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.getLastOverridden 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.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.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.types.classOrNull 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.nameForIrSerialization
import org.jetbrains.kotlin.ir.util.parentAsClass
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.utils.addToStdlib.cast import org.jetbrains.kotlin.utils.addToStdlib.cast
import kotlin.reflect.KParameter
import kotlin.reflect.KType
import kotlin.reflect.KTypeParameter 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<Variable> = mutableListOf() override val fields: MutableList<Variable> = mutableListOf()
override val typeArguments: MutableList<Variable> = mutableListOf() override val typeArguments: MutableList<Variable> = mutableListOf()
private var _parameters: List<KParameter>? = null
private var _returnType: KType? = null
private var _typeParameters: List<KTypeParameter>? = null private var _typeParameters: List<KTypeParameter>? = null
constructor(functionReference: IrFunctionReference) : this(functionReference.symbol.owner, functionReference.type.classOrNull!!.owner) constructor(functionReference: IrFunctionReference) : this(functionReference.symbol.owner, functionReference.type.classOrNull!!.owner)
constructor(irFunction: IrFunction, functionFactory: IrAbstractFunctionFactory) : constructor(irFunction: IrFunction, functionFactory: IrAbstractFunctionFactory) :
this(irFunction, functionFactory.kFunctionN(irFunction.valueParameters.size)) this(irFunction, functionFactory.kFunctionN(irFunction.valueParameters.size))
fun getParameters(interpreter: IrInterpreter): List<KParameter> {
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<KTypeParameter> { fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> {
if (_typeParameters != null) return _typeParameters!! 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!! 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("<anonymous>") || it == Name.special("<no name provided>") } private fun isLambda(): Boolean = irFunction.name.let { it == Name.special("<anonymous>") || it == Name.special("<no name provided>") }
override fun toString(): String { override fun toString(): String {
return if (isLambda()) { return if (isLambda()) renderLambda(irFunction) else renderFunction(irFunction)
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"
}
} }
} }
@@ -5,9 +5,56 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.types.classifierOrFail 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()
}
}
}
} }
@@ -5,41 +5,42 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection 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.declarations.IrProperty
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference 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.interpreter.state.State
import org.jetbrains.kotlin.ir.util.parentAsClass import org.jetbrains.kotlin.ir.types.classOrNull
import kotlin.reflect.KType
internal class KPropertyState( internal class KPropertyState(
val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State? val property: IrProperty, override val irClass: IrClass, val dispatchReceiver: State? = null, val extensionReceiver: State? = null
) : ReflectionState(property.parentAsClass.symbol) { ) : ReflectionState() {
constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?) 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 { private var _returnType: KType? = null
return dispatchReceiver != null && extensionReceiver == 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 { fun isKProperty0(): Boolean = irClass.name.asString() == "KProperty0"
return dispatchReceiver == null && extensionReceiver == null
}
fun isKProperty2(): Boolean { fun isKProperty1(): Boolean = irClass.name.asString() == "KProperty1"
return dispatchReceiver != null && extensionReceiver != null
}
fun isKMutableProperty0(): Boolean { fun isKProperty2(): Boolean = irClass.name.asString() == "KProperty2"
return isKProperty0() && property.isVar
}
fun isKMutableProperty1(): Boolean { fun isKMutableProperty0(): Boolean = irClass.name.asString() == "KMutableProperty0"
return isKProperty1() && property.isVar
}
fun isKMutableProperty2(): Boolean { fun isKMutableProperty1(): Boolean = irClass.name.asString() == "KMutableProperty1"
return isKProperty1() && property.isVar
} fun isKMutableProperty2(): Boolean = irClass.name.asString() == "KMutableProperty2"
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
if (this === other) return true if (this === other) return true
@@ -62,9 +63,6 @@ internal class KPropertyState(
} }
override fun toString(): String { override fun toString(): String {
val prefix = if (property.isVar) "var" else "val" return renderProperty(property)
val receivers = renderReceivers(property.getter?.dispatchReceiverParameter?.type, property.getter?.extensionReceiverParameter?.type)
val returnType = property.getter!!.returnType.renderType()
return "$prefix $receivers${property.name}: $returnType"
} }
} }
@@ -5,17 +5,19 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection 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.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KTypeProxy
import kotlin.reflect.KType 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<KType>? = null private var _upperBounds: List<KType>? = null
fun getUpperBounds(interpreter: IrInterpreter): List<KType> { fun getUpperBounds(interpreter: IrInterpreter): List<KType> {
if (_upperBounds != null) return _upperBounds!! 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!! return _upperBounds!!
} }
@@ -5,24 +5,43 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection 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.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.proxy.reflection.KTypeProxy
import org.jetbrains.kotlin.ir.interpreter.renderType import org.jetbrains.kotlin.ir.interpreter.renderType
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
import kotlin.reflect.KClassifier
import kotlin.reflect.KTypeProjection 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<KTypeProjection>? = null private var _arguments: List<KTypeProjection>? = 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<KTypeProjection> { fun getArguments(interpreter: IrInterpreter): List<KTypeProjection> {
if (_arguments != null) return _arguments!! if (_arguments != null) return _arguments!!
_arguments = (irType as IrSimpleType).arguments _arguments = (irType as IrSimpleType).arguments
.map { .map {
when (it.getVariance()) { when (it.getVariance()) {
Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) Variance.INVARIANT -> KTypeProjection.invariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter))
Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) Variance.IN_VARIANCE -> KTypeProjection.contravariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter))
Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!), interpreter)) Variance.OUT_VARIANCE -> KTypeProjection.covariant(KTypeProxy(KTypeState(it.typeOrNull!!, irClass), interpreter))
null -> KTypeProjection.STAR null -> KTypeProjection.STAR
} }
} }
@@ -6,28 +6,40 @@
package org.jetbrains.kotlin.ir.interpreter.state.reflection package org.jetbrains.kotlin.ir.interpreter.state.reflection
import org.jetbrains.kotlin.ir.declarations.IrClass 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.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.expressions.IrCall
import org.jetbrains.kotlin.ir.interpreter.renderType import org.jetbrains.kotlin.ir.interpreter.renderType
import org.jetbrains.kotlin.ir.interpreter.stack.Variable import org.jetbrains.kotlin.ir.interpreter.stack.Variable
import org.jetbrains.kotlin.ir.interpreter.state.State 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.IrType
import org.jetbrains.kotlin.ir.types.classOrNull import org.jetbrains.kotlin.ir.types.classOrNull
import org.jetbrains.kotlin.ir.types.classifierOrNull import org.jetbrains.kotlin.ir.types.typeOrNull
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult 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 { internal abstract class ReflectionState : State {
override val irClass: IrClass = irClassifierSymbol.extractClass()
override val fields: MutableList<Variable> = mutableListOf() override val fields: MutableList<Variable> = mutableListOf()
override val typeArguments: MutableList<Variable> = mutableListOf() override val typeArguments: MutableList<Variable> = mutableListOf()
constructor(irTypeParameter: IrTypeParameter) : this(irTypeParameter.superTypes.firstNotNullResult { it.classifierOrNull }!!)
override fun getIrFunctionByIrCall(expression: IrCall): IrFunction? = null 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 { return buildString {
if (dispatchReceiver != null) { if (dispatchReceiver != null) {
append(dispatchReceiver.renderType()) append(dispatchReceiver.renderType())
@@ -43,14 +55,26 @@ internal abstract class ReflectionState(val irClassifierSymbol: IrClassifierSymb
} }
} }
companion object { protected fun renderLambda(irFunction: IrFunction): String {
private fun IrClassifierSymbol.extractClass(): IrClass { val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.renderType()
return (owner as? IrClass) ?: (owner as IrTypeParameter).extractAnyClass() 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 { protected fun renderFunction(irFunction: IrFunction): String {
return this.superTypes val dispatchReceiver = irFunction.parentClassOrNull?.defaultType // = instanceReceiverParameter
.firstNotNullResult { it.classOrNull?.owner ?: (it.classifierOrNull?.owner as? IrTypeParameter)?.extractAnyClass() }!! 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"
} }
} }