Add support for context receivers evaluation

KTIJ-21214
This commit is contained in:
Nikita Nazarov
2022-09-19 03:50:47 +03:00
committed by Nikita Nazarov
parent bd742bb95c
commit 784ceb6baa
4 changed files with 21 additions and 4 deletions
@@ -95,8 +95,9 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
is ExtensionReceiver ->
receiver.declarationDescriptor.extensionReceiverParameter!!.type.toIrType()
is ContextReceiver -> {
val receiverParameter = receiver.declarationDescriptor.contextReceiverParameters.firstOrNull()
?: error("Unknown receiver: $receiver")
val receiverParameter = receiver.declarationDescriptor.contextReceiverParameters.find {
it.value == receiver
} ?: error("Unknown receiver: $receiver")
receiverParameter.type.toIrType()
}
else ->
@@ -17,4 +17,8 @@ class DescriptorStorageForContextReceivers {
fun getSyntheticField(receiverValue: ReceiverValue) =
syntheticFieldStorage[receiverValue] ?: error("No synthetic field for receiver value $receiverValue")
fun addAllFrom(storage: DescriptorStorageForContextReceivers) {
syntheticFieldStorage.putAll(storage.syntheticFieldStorage)
}
}
@@ -8,12 +8,14 @@ package org.jetbrains.kotlin.psi2ir.generators.fragments
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.descriptors.impl.AbstractReceiverParameterDescriptor
import org.jetbrains.kotlin.ir.declarations.IrFactory
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
import org.jetbrains.kotlin.ir.util.IdSignatureComposer
import org.jetbrains.kotlin.ir.util.NameProvider
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.resolve.scopes.receivers.ContextReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver
import org.jetbrains.kotlin.resolve.scopes.receivers.ThisClassReceiver
@@ -32,7 +34,7 @@ class FragmentCompilerSymbolTableDecorator(
if (descriptor !is ReceiverParameterDescriptor) return super.referenceValueParameter(descriptor)
val finderPredicate = when (val receiverValue = descriptor.value) {
is ExtensionReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
is ExtensionReceiver, is ContextReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
receiverValue == (targetDescriptor as? ReceiverParameterDescriptor)?.value
}
is ThisClassReceiver -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
@@ -52,8 +54,17 @@ class FragmentCompilerSymbolTableDecorator(
override fun referenceValue(value: ValueDescriptor): IrValueSymbol {
val fi = fragmentInfo ?: return super.referenceValue(value)
val finderPredicate = when (value) {
is AbstractReceiverParameterDescriptor -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
value.containingDeclaration == targetDescriptor
}
else -> { (targetDescriptor, _): EvaluatorFragmentParameterInfo ->
targetDescriptor == value
}
}
val parameterPosition =
fi.parameters.indexOfFirst { it.descriptor == value }
fi.parameters.indexOfFirst(finderPredicate)
if (parameterPosition > -1) {
return super.referenceValueParameter(fi.methodDescriptor.valueParameters[parameterPosition])
}
@@ -57,6 +57,7 @@ class FragmentModuleGenerator(
return block(fileContext).also {
symbolTableDecorator.fragmentInfo = fragmentInfo
context.additionalDescriptorStorage.addAllFrom(fileContext.additionalDescriptorStorage)
}
}