K1: Support referencing class context receivers in a form of this@Name
This commit is contained in:
+21
-14
@@ -121,20 +121,7 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
context.symbolTable.referenceValueParameter(receiverClassDescriptor.thisAsReceiverParameter)
|
||||
)
|
||||
}
|
||||
is ContextClassReceiver -> {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
val thisAsReceiverParameter = receiverClassDescriptor.thisAsReceiverParameter
|
||||
val thisReceiver = IrGetValueImpl(
|
||||
defaultStartOffset, defaultEndOffset,
|
||||
thisAsReceiverParameter.type.toIrType(),
|
||||
context.symbolTable.referenceValue(thisAsReceiverParameter)
|
||||
)
|
||||
IrGetFieldImpl(
|
||||
defaultStartOffset, defaultEndOffset,
|
||||
context.additionalDescriptorStorage.getSyntheticField(receiver).symbol,
|
||||
irReceiverType, thisReceiver
|
||||
)
|
||||
}
|
||||
is ContextClassReceiver -> loadContextReceiver(receiver, defaultStartOffset, defaultEndOffset)
|
||||
is ThisClassReceiver ->
|
||||
generateThisOrSuperReceiver(receiver, receiver.classDescriptor)
|
||||
is SuperCallReceiverValue ->
|
||||
@@ -161,6 +148,26 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
}
|
||||
}
|
||||
|
||||
fun StatementGenerator.loadContextReceiver(
|
||||
receiver: ContextClassReceiver,
|
||||
defaultStartOffset: Int, defaultEndOffset: Int,
|
||||
): IrGetFieldImpl {
|
||||
val receiverClassDescriptor = receiver.classDescriptor
|
||||
val thisAsReceiverParameter = receiverClassDescriptor.thisAsReceiverParameter
|
||||
val thisReceiver = IrGetValueImpl(
|
||||
defaultStartOffset, defaultEndOffset,
|
||||
thisAsReceiverParameter.type.toIrType(),
|
||||
context.symbolTable.referenceValue(thisAsReceiverParameter)
|
||||
)
|
||||
|
||||
return IrGetFieldImpl(
|
||||
defaultStartOffset, defaultEndOffset,
|
||||
context.additionalDescriptorStorage.getSyntheticField(receiver).symbol,
|
||||
receiver.type.toIrType(), thisReceiver
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
fun StatementGenerator.generateSingletonReference(
|
||||
descriptor: ClassDescriptor,
|
||||
startOffset: Int,
|
||||
|
||||
+15
-14
@@ -17,10 +17,7 @@
|
||||
package org.jetbrains.kotlin.psi2ir.generators
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BackendException
|
||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
@@ -46,6 +43,7 @@ import org.jetbrains.kotlin.resolve.calls.model.VariableAsFunctionResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.tasks.isDynamic
|
||||
import org.jetbrains.kotlin.resolve.constants.CompileTimeConstant
|
||||
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ContextClassReceiver
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -415,23 +413,26 @@ class StatementGenerator(
|
||||
|
||||
override fun visitThisExpression(expression: KtThisExpression, data: Nothing?): IrExpression {
|
||||
val referenceTarget = getOrFail(BindingContext.REFERENCE_TARGET, expression.instanceReference) { "No reference target for this" }
|
||||
val receiverParameter =
|
||||
getOrFail<KtReferenceExpression, ReceiverParameterDescriptor>(
|
||||
BindingContext.THIS_REFERENCE_TARGET, expression.instanceReference
|
||||
) { "No reference target for this" }
|
||||
val startOffset = expression.startOffsetSkippingComments
|
||||
val endOffset = expression.endOffset
|
||||
return when (referenceTarget) {
|
||||
is ClassDescriptor ->
|
||||
generateThisReceiver(startOffset, endOffset, referenceTarget.thisAsReceiverParameter.type, referenceTarget)
|
||||
|
||||
when (receiverParameter.value) {
|
||||
is ContextClassReceiver -> loadContextReceiver(receiverParameter.value as ContextClassReceiver, startOffset, endOffset)
|
||||
else -> generateThisReceiver(
|
||||
startOffset, endOffset, referenceTarget.thisAsReceiverParameter.type, referenceTarget
|
||||
)
|
||||
}
|
||||
is CallableDescriptor -> {
|
||||
val resolvedCall = getResolvedCall(expression)
|
||||
val receivers = listOfNotNull(referenceTarget.extensionReceiverParameter) + referenceTarget.contextReceiverParameters
|
||||
val receiver = receivers.find {
|
||||
it == resolvedCall?.candidateDescriptor
|
||||
} ?: referenceTarget.extensionReceiverParameter ?: error("No receiver: $referenceTarget")
|
||||
val receiverType = receiver.type.toIrType()
|
||||
val receiverType = receiverParameter.type.toIrType()
|
||||
IrGetValueImpl(
|
||||
startOffset, endOffset,
|
||||
receiverType,
|
||||
context.symbolTable.referenceValueParameter(receiver)
|
||||
context.symbolTable.referenceValueParameter(receiverParameter)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -513,4 +514,4 @@ abstract class StatementGeneratorExtension(val statementGenerator: StatementGene
|
||||
fun KtExpression.genStmt() = statementGenerator.generateStatement(this)
|
||||
fun KotlinType.toIrType() = with(statementGenerator) { toIrType() }
|
||||
fun translateType(kotlinType: KotlinType) = kotlinType.toIrType()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user