From 784ceb6baa99c788a2b9ed22c0f99128f979885b Mon Sep 17 00:00:00 2001 From: Nikita Nazarov Date: Mon, 19 Sep 2022 03:50:47 +0300 Subject: [PATCH] Add support for context receivers evaluation KTIJ-21214 --- .../psi2ir/generators/ArgumentsGenerationUtils.kt | 5 +++-- .../DescriptorStorageForContextReceivers.kt | 4 ++++ .../FragmentCompilerSymbolTableDecorator.kt | 15 +++++++++++++-- .../fragments/FragmentModuleGenerator.kt | 1 + 4 files changed, 21 insertions(+), 4 deletions(-) diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt index 05f4a4373ae..900fff82d3a 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/ArgumentsGenerationUtils.kt @@ -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 -> diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DescriptorStorageForContextReceivers.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DescriptorStorageForContextReceivers.kt index b866aa5446b..bc67aa0d5ab 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DescriptorStorageForContextReceivers.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/DescriptorStorageForContextReceivers.kt @@ -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) + } } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt index 41850af6889..e661e643313 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentCompilerSymbolTableDecorator.kt @@ -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]) } diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentModuleGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentModuleGenerator.kt index d759ea78f6c..4bd087f1907 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentModuleGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/fragments/FragmentModuleGenerator.kt @@ -57,6 +57,7 @@ class FragmentModuleGenerator( return block(fileContext).also { symbolTableDecorator.fragmentInfo = fragmentInfo + context.additionalDescriptorStorage.addAllFrom(fileContext.additionalDescriptorStorage) } }