Access to receiver thought reference class

This commit is contained in:
Mikhael Bogdanov
2019-11-15 14:43:00 +01:00
parent 7bab3a1048
commit be3eed5f1f
2 changed files with 24 additions and 9 deletions
@@ -22,10 +22,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.addConstructor
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrClassReferenceImpl
@@ -147,6 +144,17 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
copyAttributes(irFunctionReference)
}
private val receiverFieldFromSuper = context.ir.symbols.functionReferenceReceiverField.owner
val fakeOverrideReceiverField = functionReferenceClass.addField {
name = receiverFieldFromSuper.name
origin = IrDeclarationOrigin.FAKE_OVERRIDE
type = receiverFieldFromSuper.type
isFinal = receiverFieldFromSuper.isFinal
isStatic = receiverFieldFromSuper.isStatic
visibility = receiverFieldFromSuper.visibility
}
fun build(): IrExpression = context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol).run {
irBlock {
val constructor = createConstructor()
@@ -282,7 +290,7 @@ internal class CallableReferenceLowering(private val context: JvmBackendContext)
// will put it into a field.
if (samSuperType == null)
irImplicitCast(
irGetField(irGet(dispatchReceiverParameter!!), irSymbols.functionReferenceReceiverField.owner),
irGetField(irGet(dispatchReceiverParameter!!), fakeOverrideReceiverField),
boundReceiver.second.type
)
else
@@ -20,9 +20,7 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibilities
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.builders.declarations.buildClass
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.declarations.*
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.*
@@ -255,7 +253,7 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
// See propertyReferenceKindFor -- only one of them could ever be present.
val numOfSuperArgs = if (expression.dispatchReceiver != null || expression.extensionReceiver != null) 1 else 0
val superConstructor = superClass.constructors.single { it.valueParameters.size == numOfSuperArgs }
val receiverField = superClass.properties.single { it.name.asString() == "receiver" }.backingField!!
val backingFieldFromSuper = superClass.properties.single { it.name.asString() == "receiver" }.backingField!!
val getName = superClass.functions.single { it.name.asString() == "getName" }
val getOwner = superClass.functions.single { it.name.asString() == "getOwner" }
val getSignature = superClass.functions.single { it.name.asString() == "getSignature" }
@@ -268,6 +266,15 @@ internal class PropertyReferenceLowering(val context: JvmBackendContext) : Class
referenceClass.addOverride(getOwner) { buildReflectedContainerReference(expression) }
referenceClass.addOverride(getSignature) { irString(expression.signature) }
val receiverField = referenceClass.addField {
name = backingFieldFromSuper.name
origin = IrDeclarationOrigin.FAKE_OVERRIDE
type = backingFieldFromSuper.type
isFinal = backingFieldFromSuper.isFinal
isStatic = backingFieldFromSuper.isStatic
visibility = backingFieldFromSuper.visibility
}
val field = expression.field?.owner
if (field == null) {
fun IrBuilderWithScope.setCallArguments(call: IrCall, arguments: List<IrValueParameter>) {