[K/N] Move fields from KFunctionImpl to functions

This commit is contained in:
Pavel Kunyavskiy
2021-06-22 19:25:29 +03:00
committed by Space
parent 7a52ed73de
commit f03c897dc4
3 changed files with 66 additions and 27 deletions
@@ -14,13 +14,11 @@ import org.jetbrains.kotlin.backend.common.push
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.llvm.computeFullName
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrClassImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl
@@ -288,6 +286,53 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
}
functionReferenceClass.superTypes += superTypes
if (!isLambda) {
fun addOverrideInner(name: String, value: IrBuilderWithScope.(IrFunction) -> IrExpression) {
val overridden = functionReferenceClass.superTypes.mapNotNull { superType ->
superType.getClass()
?.declarations
?.filterIsInstance<IrSimpleFunction>()
?.singleOrNull { it.name.asString() == name }
?.symbol
}
require(overridden.isNotEmpty())
val function = functionReferenceClass.addFunction {
startOffset = SYNTHETIC_OFFSET
endOffset = SYNTHETIC_OFFSET
this.name = Name.identifier(name)
modality = Modality.FINAL
returnType = overridden[0].owner.returnType
}
function.createDispatchReceiverParameter()
function.overriddenSymbols += overridden
function.body = context.createIrBuilder(function.symbol, SYNTHETIC_OFFSET, SYNTHETIC_OFFSET).irBlockBody {
+irReturn(
value(function)
)
}
}
fun addOverride(name: String, value: IrBuilderWithScope.() -> IrExpression) {
addOverrideInner(name) { _ -> value() }
}
val kTypeGenerator = KTypeGenerator(context, irFile, functionReference)
addOverride("computeReturnType") { with(kTypeGenerator) { irKType(referencedFunction.returnType) } }
addOverride("computeArity") { irInt(unboundFunctionParameters.size + if (functionReferenceTarget.isSuspend) 1 else 0) }
addOverride("computeFlags") { irInt(getFlags()) }
val name = ((functionReferenceTarget as? IrSimpleFunction)?.attributeOwnerId as? IrSimpleFunction)?.name
?: functionReferenceTarget.name
addOverride("computeName") { irString(name.asString()) }
addOverride("computeFqName") { irString(functionReferenceTarget.computeFullName()) }
val receiver = boundFunctionParameters.singleOrNull()
if (receiver?.descriptor is ReceiverParameterDescriptor) {
addOverrideInner("computeReceiver") { f ->
irGetField(irGet(f.dispatchReceiverParameter!!), argumentToPropertiesMap[receiver]!!)
}
}
}
functionReferenceClass.addFakeOverrides(context.typeSystem)
@@ -315,27 +360,13 @@ internal class FunctionReferenceLowering(val context: Context): FileLoweringPass
type = parameter.type.substitute(typeArgumentsMap))
}
val kTypeGenerator = KTypeGenerator(context, irFile, functionReference)
body = context.createIrBuilder(symbol, startOffset, endOffset).irBlockBody {
val superConstructor = when {
isKSuspendFunction -> kSuspendFunctionImplConstructorSymbol.owner
isLambda -> irBuiltIns.anyClass.owner.constructors.single()
else -> kFunctionImplConstructorSymbol.owner
}
+irDelegatingConstructorCall(superConstructor).apply applyIrDelegationConstructorCall@ {
if (isLambda) return@applyIrDelegationConstructorCall
val name = ((functionReferenceTarget as? IrSimpleFunction)?.attributeOwnerId as? IrSimpleFunction)?.name
?: functionReferenceTarget.name
val needReceiver = boundFunctionParameters.singleOrNull()?.descriptor is ReceiverParameterDescriptor
val receiver = if (needReceiver) irGet(valueParameters.single()) else irNull()
val arity = unboundFunctionParameters.size + if (functionReferenceTarget.isSuspend) 1 else 0
putValueArgument(0, irString(name.asString()))
putValueArgument(1, irString(functionReferenceTarget.computeFullName()))
putValueArgument(2, receiver)
putValueArgument(3, irInt(arity))
putValueArgument(4, irInt(getFlags()))
putValueArgument(5, with(kTypeGenerator) { irKType(referencedFunction.returnType) })
}
+irDelegatingConstructorCall(superConstructor)
+IrInstanceInitializerCallImpl(startOffset, endOffset, functionReferenceClass.symbol, irBuiltIns.unitType)
// Save all arguments to fields.
boundFunctionParameters.forEachIndexed { index, parameter ->
@@ -9,10 +9,21 @@ import kotlin.reflect.KFunction
import kotlin.reflect.KType
@FixmeReflection
internal abstract class KFunctionImpl<out R>(
override val name: String, val fqName: String, val receiver: Any?,
val arity: Int, val flags: Int, override val returnType: KType
): KFunction<R> {
internal abstract class KFunctionImpl<out R>: KFunction<R> {
final override val returnType get() = computeReturnType()
val flags get() = computeFlags()
val arity get() = computeArity()
val fqName get() = computeFqName()
val receiver get() = computeReceiver()
final override val name get() = computeName()
abstract fun computeReturnType() : KType
abstract fun computeFlags() : Int
abstract fun computeArity() : Int
abstract fun computeFqName() : String
abstract fun computeName() : String
open fun computeReceiver(): Any? = null
override fun equals(other: Any?): Boolean {
if (other !is KFunctionImpl<*>) return false
return fqName == other.fqName && receiver == other.receiver
@@ -10,9 +10,6 @@ import kotlin.reflect.KFunction
import kotlin.reflect.KClass
@FixmeReflection
internal abstract class KSuspendFunctionImpl<out R>(
name: String, fqName: String, receiver: Any?,
arity: Int, flags: Int, returnType: KType
): KFunctionImpl<R>(name, fqName, receiver, arity, flags, returnType) {
internal abstract class KSuspendFunctionImpl<out R>: KFunctionImpl<R>() {
override fun toString() = "suspend function $name"
}