Adjust receivers for possibly synthetic properties access
Synthetic property accessors are treated as extension functions on Java classes by the front-end. However, underlying Java accessor methods are proper members.
This commit is contained in:
@@ -140,18 +140,17 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
endOffset: Int,
|
||||
call: CallBuilder
|
||||
): IrExpression {
|
||||
return call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
val getMethodDescriptor = descriptor.unwrappedGetMethod
|
||||
val superQualifierSymbol = call.superQualifier?.let { context.symbolTable.referenceClass(it) }
|
||||
|
||||
val getterDescriptor = descriptor.unwrappedGetMethod
|
||||
|
||||
if (getterDescriptor != null) {
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getterDescriptor.original)
|
||||
return if (getMethodDescriptor != null) {
|
||||
call.callReceiver.adjustForCallee(getMethodDescriptor).call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val getterSymbol = context.symbolTable.referenceFunction(getMethodDescriptor.original)
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
descriptor.type.toIrType(),
|
||||
getterSymbol,
|
||||
getterDescriptor,
|
||||
getMethodDescriptor,
|
||||
descriptor.typeParametersCount,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
@@ -160,8 +159,9 @@ class CallGenerator(statementGenerator: StatementGenerator) : StatementGenerator
|
||||
).apply {
|
||||
putTypeArguments(call.typeArguments) { it.toIrType() }
|
||||
}
|
||||
|
||||
} else {
|
||||
}
|
||||
} else {
|
||||
call.callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val fieldSymbol = context.symbolTable.referenceField(descriptor.original)
|
||||
IrGetFieldImpl(
|
||||
startOffset, endOffset,
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
|
||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
@@ -23,3 +24,27 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||
fun IrVariable.defaultLoad(): IrExpression =
|
||||
IrGetValueImpl(startOffset, endOffset, type, symbol)
|
||||
|
||||
fun CallReceiver.adjustForCallee(callee: CallableMemberDescriptor): CallReceiver =
|
||||
object : CallReceiver {
|
||||
override fun call(withDispatchAndExtensionReceivers: (IntermediateValue?, IntermediateValue?) -> IrExpression): IrExpression =
|
||||
this@adjustForCallee.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
val numReceiversPresent = listOfNotNull(dispatchReceiverValue, extensionReceiverValue).size
|
||||
val numReceiversExpected = listOfNotNull(callee.dispatchReceiverParameter, callee.extensionReceiverParameter).size
|
||||
if (numReceiversPresent != numReceiversExpected)
|
||||
throw AssertionError("Mismatching receivers for $callee: $numReceiversPresent, expected: $numReceiversExpected")
|
||||
|
||||
val newDispatchReceiverValue =
|
||||
when {
|
||||
callee.dispatchReceiverParameter == null -> null
|
||||
dispatchReceiverValue != null -> dispatchReceiverValue
|
||||
else -> extensionReceiverValue
|
||||
}
|
||||
val newExtensionReceiverValue =
|
||||
when {
|
||||
callee.extensionReceiverParameter == null -> null
|
||||
dispatchReceiverValue != null && callee.dispatchReceiverParameter == null -> dispatchReceiverValue
|
||||
else -> extensionReceiverValue
|
||||
}
|
||||
withDispatchAndExtensionReceivers(newDispatchReceiverValue, newExtensionReceiverValue)
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -141,11 +141,11 @@ class AccessorPropertyLValue(
|
||||
}
|
||||
|
||||
override fun load(): IrExpression =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
callReceiver.adjustForCallee(getterDescriptor!!).call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrGetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
type,
|
||||
getter!!, getterDescriptor!!,
|
||||
getter!!, getterDescriptor,
|
||||
typeArgumentsCount,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
@@ -157,11 +157,11 @@ class AccessorPropertyLValue(
|
||||
}
|
||||
|
||||
override fun store(irExpression: IrExpression) =
|
||||
callReceiver.call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
callReceiver.adjustForCallee(setterDescriptor!!).call { dispatchReceiverValue, extensionReceiverValue ->
|
||||
IrSetterCallImpl(
|
||||
startOffset, endOffset,
|
||||
context.irBuiltIns.unitType,
|
||||
setter!!, setterDescriptor!!,
|
||||
setter!!, setterDescriptor,
|
||||
typeArgumentsCount,
|
||||
dispatchReceiverValue?.load(),
|
||||
extensionReceiverValue?.load(),
|
||||
|
||||
Reference in New Issue
Block a user