diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index d71abb81618..43248fa4d1b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -965,8 +965,8 @@ public class DescriptorResolver { receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true); AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER)); receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( - propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER), - false); + propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER) + ); receiverToLabelMap.put(receiverDescriptor, receiverTypeRef.nameForReceiverLabel()); } @@ -1046,9 +1046,9 @@ public class DescriptorResolver { return Lists.reverse(contextReceivers).stream().map(contextReceiver -> { KotlinType receiverType = contextReceiversToTypes.get(contextReceiver); AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER)); - ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( - propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER), - true); + ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createContextReceiverParameterForCallable( + propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER) + ); String contextReceiverName = contextReceiver.name(); if (contextReceiverName != null) { receiverToLabelMap.put(receiverDescriptor, contextReceiverName); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 83d83e549b6..222911ec8fe 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -232,7 +232,7 @@ class FunctionDescriptorResolver( val extensionReceiver = receiverType?.let { val splitter = AnnotationSplitter(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) DescriptorFactory.createExtensionReceiverParameterForCallable( - functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER), false + functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER) ) }?.apply { val extensionReceiverName = receiverTypeRef?.nameForReceiverLabel() @@ -243,15 +243,16 @@ class FunctionDescriptorResolver( val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { type -> val splitter = AnnotationSplitter(storageManager, type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) - DescriptorFactory.createExtensionReceiverParameterForCallable( - functionDescriptor, type, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER), true + DescriptorFactory.createContextReceiverParameterForCallable( + functionDescriptor, type, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER) ) } - contextReceiverDescriptors.reversed().zip(contextReceivers.lastIndex downTo 0).forEach { (contextReceiverDescriptor, i) -> - contextReceivers[i].name()?.let { - receiverToLabelMap[contextReceiverDescriptor] = it + contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed() + .forEach { (contextReceiverDescriptor, i) -> + contextReceivers[i].name()?.let { + receiverToLabelMap[contextReceiverDescriptor] = it + } } - } trace.record(BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, functionDescriptor, receiverToLabelMap) functionDescriptor.initialize( extensionReceiver, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java index d2319286559..98c8d6a135e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/types/expressions/BasicExpressionTypingVisitor.java @@ -66,6 +66,7 @@ import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker; import org.jetbrains.kotlin.resolve.constants.*; import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind; import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; +import org.jetbrains.kotlin.resolve.scopes.receivers.ContextReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; @@ -599,7 +600,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor { else if (!receivers.isEmpty()) { // `this` cannot point to context receiver for (ReceiverParameterDescriptor receiver : receivers) { - if (!(receiver.getValue() instanceof ExtensionReceiver) || !((ExtensionReceiver) receiver.getValue()).isContextReceiver()) { + if (!(receiver.getValue() instanceof ContextReceiver)) { result = receiver; break; } 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 e7caf63df6c..f1a7939d5e1 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,11 +95,11 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue { val irReceiverType = when (receiver) { - is ExtensionReceiver -> { - val receiverParameters = - receiver.declarationDescriptor.contextReceiverParameters + listOfNotNull(receiver.declarationDescriptor.extensionReceiverParameter) - val receiverParameter = receiverParameters.firstOrNull { it.value == receiver } - ?: receiver.declarationDescriptor.extensionReceiverParameter!! + is ExtensionReceiver -> + receiver.declarationDescriptor.extensionReceiverParameter!!.type.toIrType() + is ContextReceiver -> { + val receiverParameter = receiver.declarationDescriptor.contextReceiverParameters.firstOrNull() + ?: error("Unknown receiver: $receiver") receiverParameter.type.toIrType() } else -> @@ -142,10 +142,14 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse is ExpressionReceiver -> generateExpression(receiver.expression) is ExtensionReceiver -> { - val receiverParameters = listOfNotNull(receiver.declarationDescriptor.extensionReceiverParameter) + - receiver.declarationDescriptor.contextReceiverParameters - val receiverParameter = receiverParameters.singleOrNull { it.value == receiver } - ?: receiver.declarationDescriptor.extensionReceiverParameter!! + IrGetValueImpl( + defaultStartOffset, defaultStartOffset, irReceiverType, + context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!) + ) + } + is ContextReceiver -> { + val receiverParameter = receiver.declarationDescriptor.contextReceiverParameters + .single { it.value == receiver } IrGetValueImpl( defaultStartOffset, defaultStartOffset, irReceiverType, context.symbolTable.referenceValueParameter(receiverParameter) diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java index 9569a170811..eac53316e88 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.impl.*; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.resolve.scopes.receivers.ContextReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.Variance; @@ -189,18 +190,19 @@ public class DescriptorFactory { @Nullable KotlinType receiverParameterType, @NotNull Annotations annotations ) { - return createExtensionReceiverParameterForCallable(owner, receiverParameterType, annotations, false); + return receiverParameterType == null + ? null + : new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType, null), annotations); } @Nullable - public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable( + public static ReceiverParameterDescriptor createContextReceiverParameterForCallable( @NotNull CallableDescriptor owner, @Nullable KotlinType receiverParameterType, - @NotNull Annotations annotations, - boolean isContextReceiver + @NotNull Annotations annotations ) { return receiverParameterType == null ? null - : new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType, null, isContextReceiver), annotations); + : new ReceiverParameterDescriptorImpl(owner, new ContextReceiver(owner, receiverParameterType, null), annotations); } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextReceiver.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextReceiver.kt new file mode 100644 index 00000000000..f8602304ac8 --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextReceiver.kt @@ -0,0 +1,19 @@ +/* + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.resolve.scopes.receivers + +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.types.KotlinType + +class ContextReceiver( + override val declarationDescriptor: CallableDescriptor, + receiverType: KotlinType, + original: ReceiverValue? +) : AbstractReceiverValue(receiverType, original), ImplicitReceiver { + override fun replaceType(newType: KotlinType): ReceiverValue = ContextReceiver(declarationDescriptor, newType, original) + + override fun toString(): String = "Cxt { $declarationDescriptor }" +} \ No newline at end of file diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ExtensionReceiver.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ExtensionReceiver.java index 2bf90d2a00f..a871e09a89d 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ExtensionReceiver.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ExtensionReceiver.java @@ -35,25 +35,14 @@ import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker; public class ExtensionReceiver extends AbstractReceiverValue implements ImplicitReceiver { private final CallableDescriptor descriptor; - private final boolean isContextReceiver; public ExtensionReceiver( @NotNull CallableDescriptor callableDescriptor, @NotNull KotlinType receiverType, @Nullable ReceiverValue original - ) { - this(callableDescriptor, receiverType, original, false); - } - - public ExtensionReceiver( - @NotNull CallableDescriptor callableDescriptor, - @NotNull KotlinType receiverType, - @Nullable ReceiverValue original, - boolean isContextReceiver ) { super(receiverType, original); this.descriptor = callableDescriptor; - this.isContextReceiver = isContextReceiver; } @NotNull @@ -72,8 +61,4 @@ public class ExtensionReceiver extends AbstractReceiverValue implements Implicit public String toString() { return getType() + ": Ext {" + descriptor + "}"; } - - public boolean isContextReceiver() { - return isContextReceiver; - } }