Access this through the dispatch parameter when available
This commit is contained in:
committed by
Georgy Bronnikov
parent
9b9236efcb
commit
b04dc69157
+2
-2
@@ -234,7 +234,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
functionReferenceClass = buildClass {
|
||||
setSourceRange(irFunctionReference)
|
||||
origin = JvmLoweredDeclarationOrigin.FUNCTION_REFERENCE_IMPL
|
||||
name = "${callee.name}\$${functionReferenceCount++}".synthesizedName
|
||||
name = "${callee.name.safeName()}\$${functionReferenceCount++}".synthesizedName
|
||||
kind = ClassKind.CLASS
|
||||
visibility = Visibilities.PUBLIC
|
||||
modality = Modality.FINAL
|
||||
@@ -403,7 +403,7 @@ internal class CallableReferenceLowering(val context: JvmBackendContext) : FileL
|
||||
val argument = when {
|
||||
!unboundArgsSet.contains(parameter) ->
|
||||
// Bound parameter - read from field.
|
||||
irGetField(irGet(functionReferenceThis.owner), argumentToFieldMap[parameter]!!)
|
||||
irGetField(irGet(dispatchReceiverParameter!!), argumentToFieldMap[parameter]!!)
|
||||
function.isSuspend && unboundIndex == valueParameters.size ->
|
||||
// For suspend functions the last argument is continuation and it is implicit.
|
||||
TODO()
|
||||
|
||||
+1
-1
@@ -111,7 +111,7 @@ private class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : Cl
|
||||
target.returnType,
|
||||
target.returnType.classifierOrFail,
|
||||
irCall(target).apply {
|
||||
dispatchReceiver = irGet(irClass.thisReceiver!!)
|
||||
dispatchReceiver = irGet(dispatchReceiverParameter!!)
|
||||
target.valueParameters.forEachIndexed { i, irValueParameter ->
|
||||
val type = irValueParameter.type
|
||||
putValueArgument(
|
||||
|
||||
+38
-29
@@ -292,70 +292,79 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
|
||||
}
|
||||
}
|
||||
|
||||
fun buildOverride(method: IrSimpleFunction, build: IrBlockBodyBuilder.(List<IrValueParameter>) -> IrExpression) =
|
||||
buildFun {
|
||||
setSourceRange(expression)
|
||||
name = method.name
|
||||
returnType = method.returnType
|
||||
visibility = method.visibility
|
||||
origin = referenceClass.origin
|
||||
}.apply {
|
||||
parent = referenceClass
|
||||
referenceClass.declarations.add(this)
|
||||
|
||||
overriddenSymbols.add(method.symbol)
|
||||
dispatchReceiverParameter = referenceThis.copyTo(this)
|
||||
for (parameter in method.valueParameters)
|
||||
valueParameters.add(parameter.copyTo(this))
|
||||
body = context.createIrBuilder(symbol).irBlockBody(startOffset, endOffset) {
|
||||
+irReturn(build(valueParameters))
|
||||
}
|
||||
fun buildOverride(
|
||||
method: IrSimpleFunction,
|
||||
build: IrBlockBodyBuilder.(IrValueParameter, List<IrValueParameter>) -> IrExpression
|
||||
) = referenceClass.addFunction {
|
||||
setSourceRange(expression)
|
||||
name = method.name
|
||||
returnType = method.returnType
|
||||
visibility = method.visibility
|
||||
origin = referenceClass.origin
|
||||
}.apply {
|
||||
overriddenSymbols.add(method.symbol)
|
||||
val thisParameter = referenceThis.copyTo(this)
|
||||
dispatchReceiverParameter = thisParameter
|
||||
for (parameter in method.valueParameters)
|
||||
valueParameters.add(parameter.copyTo(this))
|
||||
body = context.createIrBuilder(symbol).irBlockBody(startOffset, endOffset) {
|
||||
+irReturn(build(thisParameter, valueParameters))
|
||||
}
|
||||
}
|
||||
|
||||
val receiverField = superClass.properties.single { it.name.asString() == "receiver" }.backingField!!
|
||||
fun IrBuilderWithScope.setReceiversOn(call: IrCall, valueParameters: List<IrValueParameter>) {
|
||||
fun IrBuilderWithScope.setReceiversOn(
|
||||
call: IrCall,
|
||||
dispatchReceiverParameter: IrValueParameter,
|
||||
valueParameters: List<IrValueParameter>
|
||||
) {
|
||||
var index = 0
|
||||
call.dispatchReceiver = call.symbol.owner.dispatchReceiverParameter?.let {
|
||||
if (expression.dispatchReceiver != null)
|
||||
irGetField(irGet(referenceThis), receiverField)
|
||||
irGetField(irGet(dispatchReceiverParameter), receiverField)
|
||||
else
|
||||
irImplicitCast(irGet(valueParameters[index++]), it.type)
|
||||
}
|
||||
call.extensionReceiver = call.symbol.owner.extensionReceiverParameter?.let {
|
||||
if (expression.extensionReceiver != null)
|
||||
irGetField(irGet(referenceThis), receiverField)
|
||||
irGetField(irGet(dispatchReceiverParameter), receiverField)
|
||||
else
|
||||
irImplicitCast(irGet(valueParameters[index++]), it.type)
|
||||
}
|
||||
}
|
||||
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "getName" }) {
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "getName" }) { _, _ ->
|
||||
irString(expression.descriptor.name.asString())
|
||||
}
|
||||
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "getOwner" }) {
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "getOwner" }) { _, _ ->
|
||||
buildReflectedContainerReference(expression)
|
||||
}
|
||||
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "getSignature" }) {
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "getSignature" }) { _, _ ->
|
||||
irString(expression.signature)
|
||||
}
|
||||
|
||||
expression.getter?.owner?.let { getter ->
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "get" }) { valueParameters ->
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "get" }) { dispatchReceiverParameter, valueParameters ->
|
||||
irGet(getter.returnType, null, getter.symbol).apply {
|
||||
copyTypeArgumentsFrom(expression)
|
||||
setReceiversOn(this, valueParameters)
|
||||
setReceiversOn(
|
||||
this,
|
||||
dispatchReceiverParameter,
|
||||
valueParameters
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
expression.setter?.owner?.let { setter ->
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "set" }) { valueParameters ->
|
||||
val value = irGet(valueParameters.last())
|
||||
buildOverride(superClass.functions.single { it.name.asString() == "set" }) { dispatchReceiverParameter, valueParameters ->
|
||||
val type = setter.valueParameters.last().type
|
||||
val value = irImplicitCast(irGet(valueParameters.last()), type)
|
||||
irSet(setter.returnType, null, setter.symbol, value).apply {
|
||||
copyTypeArgumentsFrom(expression)
|
||||
setReceiversOn(this, valueParameters)
|
||||
setReceiversOn(this, dispatchReceiverParameter, valueParameters)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user