Implement interpretation for KType and KTypeParameter
This commit is contained in:
committed by
TeamCityServer
parent
88b5b5f702
commit
5a95e5b45f
@@ -27,6 +27,7 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
import org.jetbrains.kotlin.util.capitalizeDecapitalize.capitalizeAsciiOnly
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
import java.lang.invoke.MethodType
|
import java.lang.invoke.MethodType
|
||||||
|
import kotlin.math.min
|
||||||
|
|
||||||
internal fun IrFunction.getDispatchReceiver(): IrValueParameterSymbol? = this.dispatchReceiverParameter?.symbol
|
internal fun IrFunction.getDispatchReceiver(): IrValueParameterSymbol? = this.dispatchReceiverParameter?.symbol
|
||||||
|
|
||||||
@@ -225,6 +226,24 @@ internal fun IrType.isInterface() = classOrNull?.owner?.kind == ClassKind.INTERF
|
|||||||
|
|
||||||
internal fun IrType.isThrowable() = this.getClass()?.fqNameWhenAvailable?.asString() == "kotlin.Throwable"
|
internal fun IrType.isThrowable() = this.getClass()?.fqNameWhenAvailable?.asString() == "kotlin.Throwable"
|
||||||
|
|
||||||
|
internal fun IrType.renderType(): String {
|
||||||
|
var renderedType = this.render()
|
||||||
|
do {
|
||||||
|
val index = renderedType.indexOf(" of ")
|
||||||
|
if (index == -1) break
|
||||||
|
val replaceUntilComma = renderedType.indexOf(',', index)
|
||||||
|
val replaceUntilTriangle = renderedType.indexOf('>', index)
|
||||||
|
val replaceUntil = when {
|
||||||
|
replaceUntilComma == -1 && replaceUntilTriangle == -1 -> renderedType.length
|
||||||
|
replaceUntilComma == -1 -> replaceUntilTriangle
|
||||||
|
replaceUntilTriangle == -1 -> replaceUntilComma
|
||||||
|
else -> min(replaceUntilComma, replaceUntilTriangle)
|
||||||
|
}
|
||||||
|
renderedType = renderedType.replaceRange(index, replaceUntil, "")
|
||||||
|
} while (true)
|
||||||
|
return renderedType
|
||||||
|
}
|
||||||
|
|
||||||
fun IrClass.internalName(): String {
|
fun IrClass.internalName(): String {
|
||||||
val internalName = StringBuilder(this.name.asString())
|
val internalName = StringBuilder(this.name.asString())
|
||||||
generateSequence(this as? IrDeclarationParent) { (it as? IrDeclaration)?.parent }
|
generateSequence(this as? IrDeclarationParent) { (it as? IrDeclaration)?.parent }
|
||||||
|
|||||||
+15
-4
@@ -188,9 +188,14 @@ class IrCompileTimeChecker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?): Boolean {
|
override fun visitFunctionReference(expression: IrFunctionReference, data: Nothing?): Boolean {
|
||||||
return expression.asVisited {
|
val owner = expression.symbol.owner
|
||||||
mode.canEvaluateFunction(expression.symbol.owner) && expression.symbol.owner.body?.accept(this, data) == true
|
if (!mode.canEvaluateFunction(owner)) return false
|
||||||
}
|
|
||||||
|
val dispatchReceiverComputable = expression.dispatchReceiver?.accept(this, null) ?: true
|
||||||
|
val extensionReceiverComputable = expression.extensionReceiver?.accept(this, null) ?: true
|
||||||
|
val bodyComputable = owner.asVisited { if (mode.canEvaluateBody(owner)) owner.body?.accept(this, null) ?: true else true }
|
||||||
|
|
||||||
|
return dispatchReceiverComputable && extensionReceiverComputable && bodyComputable
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?): Boolean {
|
override fun visitFunctionExpression(expression: IrFunctionExpression, data: Nothing?): Boolean {
|
||||||
@@ -261,6 +266,12 @@ class IrCompileTimeChecker(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClassReference(expression: IrClassReference, data: Nothing?): Boolean {
|
override fun visitClassReference(expression: IrClassReference, data: Nothing?): Boolean {
|
||||||
return with(mode) { (expression.symbol.owner as IrClass).isMarkedAsCompileTime() }
|
return with(mode) {
|
||||||
|
when (this) {
|
||||||
|
EvaluationMode.FULL -> true
|
||||||
|
EvaluationMode.WITH_ANNOTATIONS -> (expression.symbol.owner as IrClass).isMarkedAsCompileTime()
|
||||||
|
EvaluationMode.ONLY_BUILTINS -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-1
@@ -8,6 +8,7 @@ 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.KPropertyState
|
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.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
|
||||||
@@ -38,7 +39,7 @@ 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() = TODO("Not yet implemented")
|
get() = KTypeProxy(KTypeState(propertyType), interpreter)
|
||||||
override val visibility: KVisibility?
|
override val visibility: KVisibility?
|
||||||
get() = state.irClass.visibility.toKVisibility()
|
get() = state.irClass.visibility.toKVisibility()
|
||||||
|
|
||||||
|
|||||||
+10
-8
@@ -6,7 +6,6 @@
|
|||||||
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
package org.jetbrains.kotlin.ir.interpreter.proxy.reflection
|
||||||
|
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities
|
|
||||||
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
|
||||||
@@ -17,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.asString() // TODO return null if class has no name
|
get() = state.irClass.name.takeIf { !it.isSpecial }?.asString()
|
||||||
override val qualifiedName: String?
|
override val qualifiedName: String?
|
||||||
get() = state.irClass.internalName()
|
get() = if (!state.irClass.name.isSpecial) state.irClass.internalName() else null
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override val constructors: Collection<KFunction<Proxy>>
|
override val constructors: Collection<KFunction<Proxy>>
|
||||||
@@ -31,9 +30,9 @@ internal class KClassProxy(
|
|||||||
override val objectInstance: Proxy?
|
override val objectInstance: Proxy?
|
||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
override val typeParameters: List<KTypeParameter>
|
override val typeParameters: List<KTypeParameter>
|
||||||
get() = TODO("Not yet implemented")
|
get() = state.getTypeParameters(interpreter)
|
||||||
override val supertypes: List<KType>
|
override val supertypes: List<KType>
|
||||||
get() = TODO("Not yet implemented")
|
get() = state.getSupertypes(interpreter)
|
||||||
override val sealedSubclasses: List<KClass<out Proxy>>
|
override val sealedSubclasses: List<KClass<out Proxy>>
|
||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
override val annotations: List<Annotation>
|
override val annotations: List<Annotation>
|
||||||
@@ -65,14 +64,17 @@ internal class KClassProxy(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
TODO("Not yet implemented")
|
if (this === other) return true
|
||||||
|
if (other !is KClassProxy) return false
|
||||||
|
|
||||||
|
return state == other.state
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun hashCode(): Int {
|
override fun hashCode(): Int {
|
||||||
TODO("Not yet implemented")
|
return state.hashCode()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
TODO("Not yet implemented")
|
return state.toString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-2
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
|||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
import org.jetbrains.kotlin.ir.interpreter.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState
|
import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.KTypeState
|
||||||
import org.jetbrains.kotlin.ir.interpreter.toState
|
import org.jetbrains.kotlin.ir.interpreter.toState
|
||||||
import org.jetbrains.kotlin.ir.util.isSuspend
|
import org.jetbrains.kotlin.ir.util.isSuspend
|
||||||
import kotlin.reflect.*
|
import kotlin.reflect.*
|
||||||
@@ -37,9 +38,9 @@ internal class KFunctionProxy(
|
|||||||
override val parameters: List<KParameter>
|
override val parameters: List<KParameter>
|
||||||
get() = TODO("Not yet implemented")
|
get() = TODO("Not yet implemented")
|
||||||
override val returnType: KType
|
override val returnType: KType
|
||||||
get() = TODO("Not yet implemented")
|
get() = KTypeProxy(KTypeState(state.irFunction.returnType), interpreter)
|
||||||
override val typeParameters: List<KTypeParameter>
|
override val typeParameters: List<KTypeParameter>
|
||||||
get() = TODO("Not yet implemented")
|
get() = state.getTypeParameters(interpreter)
|
||||||
|
|
||||||
override fun call(vararg args: Any?): Any? {
|
override fun call(vararg args: Any?): Any? {
|
||||||
var index = 0
|
var index = 0
|
||||||
|
|||||||
+39
@@ -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.KTypeParameterState
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
import kotlin.reflect.*
|
||||||
|
|
||||||
|
internal class KTypeParameterProxy(
|
||||||
|
override val state: KTypeParameterState, override val interpreter: IrInterpreter
|
||||||
|
) : ReflectionProxy, KTypeParameter {
|
||||||
|
override val name: String
|
||||||
|
get() = state.irTypeParameter.name.asString()
|
||||||
|
override val upperBounds: List<KType>
|
||||||
|
get() = state.getUpperBounds(interpreter)
|
||||||
|
override val variance: KVariance
|
||||||
|
get() = when (state.irTypeParameter.variance) {
|
||||||
|
Variance.INVARIANT -> KVariance.INVARIANT
|
||||||
|
Variance.IN_VARIANCE -> KVariance.IN
|
||||||
|
Variance.OUT_VARIANCE -> KVariance.OUT
|
||||||
|
}
|
||||||
|
override val isReified: Boolean
|
||||||
|
get() = state.irTypeParameter.isReified
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is KTypeParameterProxy) return false
|
||||||
|
|
||||||
|
return state == other.state
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = state.hashCode()
|
||||||
|
|
||||||
|
override fun toString(): String = state.toString()
|
||||||
|
}
|
||||||
+44
@@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* 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.declarations.IrClass
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.KClassState
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.KTypeParameterState
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.KTypeState
|
||||||
|
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||||
|
import org.jetbrains.kotlin.ir.types.isMarkedNullable
|
||||||
|
import kotlin.reflect.KClassifier
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
override val arguments: List<KTypeProjection>
|
||||||
|
get() = state.getArguments(interpreter)
|
||||||
|
override val isMarkedNullable: Boolean
|
||||||
|
get() = state.irType.isMarkedNullable()
|
||||||
|
override val annotations: List<Annotation>
|
||||||
|
get() = TODO("Not yet implemented")
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
if (this === other) return true
|
||||||
|
if (other !is KTypeProxy) return false
|
||||||
|
|
||||||
|
return state == other.state
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = state.hashCode()
|
||||||
|
|
||||||
|
override fun toString(): String = state.toString()
|
||||||
|
}
|
||||||
+4
@@ -9,9 +9,11 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
import org.jetbrains.kotlin.ir.interpreter.proxy.Proxy
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.*
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.KClassState
|
import org.jetbrains.kotlin.ir.interpreter.state.KClassState
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState
|
import org.jetbrains.kotlin.ir.interpreter.state.KFunctionState
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
import org.jetbrains.kotlin.ir.interpreter.state.KPropertyState
|
||||||
|
import org.jetbrains.kotlin.ir.interpreter.state.KTypeState
|
||||||
import org.jetbrains.kotlin.ir.interpreter.state.ReflectionState
|
import org.jetbrains.kotlin.ir.interpreter.state.ReflectionState
|
||||||
import kotlin.reflect.KVisibility
|
import kotlin.reflect.KVisibility
|
||||||
|
|
||||||
@@ -40,6 +42,8 @@ internal interface ReflectionProxy : Proxy {
|
|||||||
}
|
}
|
||||||
is KFunctionState -> KFunctionProxy(this, interpreter)
|
is KFunctionState -> KFunctionProxy(this, interpreter)
|
||||||
is KClassState -> KClassProxy(this, interpreter)
|
is KClassState -> KClassProxy(this, interpreter)
|
||||||
|
is KTypeState -> KTypeProxy(this, interpreter)
|
||||||
|
is KTypeParameterState -> KTypeParameterProxy(this, interpreter)
|
||||||
else -> TODO("not supported reference state")
|
else -> TODO("not supported reference state")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+156
-18
@@ -13,47 +13,67 @@ import org.jetbrains.kotlin.ir.expressions.IrFunctionReference
|
|||||||
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
|
import org.jetbrains.kotlin.ir.expressions.IrPropertyReference
|
||||||
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.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.KFunctionProxy
|
||||||
import org.jetbrains.kotlin.ir.interpreter.proxy.reflection.KProperty1Proxy
|
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.stack.Variable
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol
|
||||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
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.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
import org.jetbrains.kotlin.types.Variance
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
||||||
import kotlin.reflect.KCallable
|
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||||
import kotlin.reflect.KFunction
|
import kotlin.reflect.*
|
||||||
|
|
||||||
internal abstract class ReflectionState(override val irClass: IrClass) : State {
|
internal abstract class ReflectionState(val irClassifierSymbol: IrClassifierSymbol) : 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 renderReceivers(dispatchReceiver: IrType?, extensionReceiver: IrType?): String {
|
||||||
return buildString {
|
return buildString {
|
||||||
if (dispatchReceiver != null) {
|
if (dispatchReceiver != null) {
|
||||||
append(dispatchReceiver.render())
|
append(dispatchReceiver.renderType())
|
||||||
append(".")
|
append(".")
|
||||||
}
|
}
|
||||||
val addParentheses = dispatchReceiver != null && extensionReceiver != null
|
val addParentheses = dispatchReceiver != null && extensionReceiver != null
|
||||||
if (addParentheses) append("(")
|
if (addParentheses) append("(")
|
||||||
if (extensionReceiver != null) {
|
if (extensionReceiver != null) {
|
||||||
append(extensionReceiver.render())
|
append(extensionReceiver.renderType())
|
||||||
append(".")
|
append(".")
|
||||||
}
|
}
|
||||||
if (addParentheses) append(")")
|
if (addParentheses) append(")")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private fun IrClassifierSymbol.extractClass(): IrClass {
|
||||||
|
return (owner as? IrClass) ?: (owner as IrTypeParameter).extractAnyClass()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun IrTypeParameter.extractAnyClass(): IrClass {
|
||||||
|
return this.superTypes
|
||||||
|
.firstNotNullResult { it.classOrNull?.owner ?: (it.classifierOrNull?.owner as? IrTypeParameter)?.extractAnyClass() }!!
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class KClassState(override val irClass: IrClass) : ReflectionState(irClass) {
|
internal class KClassState(override val irClass: IrClass) : ReflectionState(irClass.symbol) {
|
||||||
private var _members: Collection<KCallable<*>>? = null
|
private var _members: Collection<KCallable<*>>? = null
|
||||||
private var _constructors: Collection<KFunction<Proxy>>? = null
|
private var _constructors: Collection<KFunction<Proxy>>? = null
|
||||||
|
private var _typeParameters: List<KTypeParameter>? = 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)
|
||||||
|
|
||||||
@@ -78,11 +98,43 @@ internal class KClassState(override val irClass: IrClass) : ReflectionState(irCl
|
|||||||
.map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) as KFunction<Proxy> }
|
.map { KFunctionProxy(KFunctionState(it, interpreter.irBuiltIns.functionFactory), interpreter) as KFunction<Proxy> }
|
||||||
return _constructors!!
|
return _constructors!!
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> {
|
||||||
|
if (_typeParameters != null) return _typeParameters!!
|
||||||
|
_typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) }
|
||||||
|
return _typeParameters!!
|
||||||
|
}
|
||||||
|
|
||||||
|
fun getSupertypes(interpreter: IrInterpreter): List<KType> {
|
||||||
|
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(
|
internal class KPropertyState(
|
||||||
val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State?
|
val property: IrProperty, val dispatchReceiver: State?, val extensionReceiver: State?
|
||||||
) : ReflectionState(property.parentAsClass) {
|
) : ReflectionState(property.parentAsClass.symbol) {
|
||||||
constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?)
|
constructor(propertyReference: IrPropertyReference, dispatchReceiver: State?, extensionReceiver: State?)
|
||||||
: this(propertyReference.symbol.owner, dispatchReceiver, extensionReceiver)
|
: this(propertyReference.symbol.owner, dispatchReceiver, extensionReceiver)
|
||||||
|
|
||||||
@@ -133,18 +185,25 @@ internal class KPropertyState(
|
|||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
val prefix = if (property.isVar) "var" else "val"
|
val prefix = if (property.isVar) "var" else "val"
|
||||||
val receivers = renderReceivers(property.getter?.dispatchReceiverParameter?.type, property.getter?.extensionReceiverParameter?.type)
|
val receivers = renderReceivers(property.getter?.dispatchReceiverParameter?.type, property.getter?.extensionReceiverParameter?.type)
|
||||||
val returnType = property.getter!!.returnType.render()
|
val returnType = property.getter!!.returnType.renderType()
|
||||||
return "$prefix $receivers${property.name}: $returnType"
|
return "$prefix $receivers${property.name}: $returnType"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass) {
|
internal class KFunctionState(val irFunction: IrFunction, override val irClass: IrClass) : ReflectionState(irClass.symbol) {
|
||||||
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 _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.functionN(irFunction.valueParameters.size))
|
this(irFunction, functionFactory.kFunctionN(irFunction.valueParameters.size))
|
||||||
|
|
||||||
|
fun getTypeParameters(interpreter: IrInterpreter): List<KTypeParameter> {
|
||||||
|
if (_typeParameters != null) return _typeParameters!!
|
||||||
|
_typeParameters = irClass.typeParameters.map { KTypeParameterProxy(KTypeParameterState(it), interpreter) }
|
||||||
|
return _typeParameters!!
|
||||||
|
}
|
||||||
|
|
||||||
private val invokeSymbol = irClass.declarations
|
private val invokeSymbol = irClass.declarations
|
||||||
.single { it.nameForIrSerialization.asString() == "invoke" }
|
.single { it.nameForIrSerialization.asString() == "invoke" }
|
||||||
@@ -163,17 +222,96 @@ internal class KFunctionState(val irFunction: IrFunction, override val irClass:
|
|||||||
|
|
||||||
override fun toString(): String {
|
override fun toString(): String {
|
||||||
return if (isLambda()) {
|
return if (isLambda()) {
|
||||||
val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.render()
|
val receiver = (irFunction.dispatchReceiverParameter?.type ?: irFunction.extensionReceiverParameter?.type)?.renderType()
|
||||||
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() }
|
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() }
|
||||||
val returnType = irFunction.returnType.render()
|
val returnType = irFunction.returnType.renderType()
|
||||||
("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it }
|
("$arguments -> $returnType").let { if (receiver != null) "$receiver.$it" else it }
|
||||||
} else {
|
} else {
|
||||||
val dispatchReceiver = irFunction.parentAsClass.defaultType // = instanceReceiverParameter
|
val dispatchReceiver = irFunction.parentAsClass.defaultType // = instanceReceiverParameter
|
||||||
val extensionReceiver = irFunction.extensionReceiverParameter?.type
|
val extensionReceiver = irFunction.extensionReceiverParameter?.type
|
||||||
val receivers = if (irFunction is IrConstructor) "" else renderReceivers(dispatchReceiver, extensionReceiver)
|
val receivers = if (irFunction is IrConstructor) "" else renderReceivers(dispatchReceiver, extensionReceiver)
|
||||||
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.render() }
|
val arguments = irFunction.valueParameters.joinToString(prefix = "(", postfix = ")") { it.type.renderType() }
|
||||||
val returnType = irFunction.returnType.render()
|
val returnType = irFunction.returnType.renderType()
|
||||||
"fun $receivers${irFunction.name}$arguments: $returnType"
|
"fun $receivers${irFunction.name}$arguments: $returnType"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal class KTypeState(val irType: IrType) : ReflectionState(irType.classifierOrFail) {
|
||||||
|
private var _arguments: List<KTypeProjection>? = null
|
||||||
|
|
||||||
|
fun getArguments(interpreter: IrInterpreter): List<KTypeProjection> {
|
||||||
|
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<KType>? = null
|
||||||
|
|
||||||
|
fun getUpperBounds(interpreter: IrInterpreter): List<KType> {
|
||||||
|
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) {
|
||||||
|
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user