[FE] Create separate class for context receiver value

This commit is contained in:
Anastasiya Shadrina
2021-09-27 17:33:10 +07:00
committed by TeamCityServer
parent d980136593
commit 1357f28be6
7 changed files with 54 additions and 42 deletions
@@ -965,8 +965,8 @@ public class DescriptorResolver {
receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true); receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER)); AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER), propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
false); );
receiverToLabelMap.put(receiverDescriptor, receiverTypeRef.nameForReceiverLabel()); receiverToLabelMap.put(receiverDescriptor, receiverTypeRef.nameForReceiverLabel());
} }
@@ -1046,9 +1046,9 @@ public class DescriptorResolver {
return Lists.reverse(contextReceivers).stream().map(contextReceiver -> { return Lists.reverse(contextReceivers).stream().map(contextReceiver -> {
KotlinType receiverType = contextReceiversToTypes.get(contextReceiver); KotlinType receiverType = contextReceiversToTypes.get(contextReceiver);
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER)); AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createContextReceiverParameterForCallable(
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER), propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
true); );
String contextReceiverName = contextReceiver.name(); String contextReceiverName = contextReceiver.name();
if (contextReceiverName != null) { if (contextReceiverName != null) {
receiverToLabelMap.put(receiverDescriptor, contextReceiverName); receiverToLabelMap.put(receiverDescriptor, contextReceiverName);
@@ -232,7 +232,7 @@ class FunctionDescriptorResolver(
val extensionReceiver = receiverType?.let { val extensionReceiver = receiverType?.let {
val splitter = AnnotationSplitter(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) val splitter = AnnotationSplitter(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
DescriptorFactory.createExtensionReceiverParameterForCallable( DescriptorFactory.createExtensionReceiverParameterForCallable(
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER), false functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
) )
}?.apply { }?.apply {
val extensionReceiverName = receiverTypeRef?.nameForReceiverLabel() val extensionReceiverName = receiverTypeRef?.nameForReceiverLabel()
@@ -243,15 +243,16 @@ class FunctionDescriptorResolver(
val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { type -> val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { type ->
val splitter = AnnotationSplitter(storageManager, type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) val splitter = AnnotationSplitter(storageManager, type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
DescriptorFactory.createExtensionReceiverParameterForCallable( DescriptorFactory.createContextReceiverParameterForCallable(
functionDescriptor, type, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER), true functionDescriptor, type, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
) )
} }
contextReceiverDescriptors.reversed().zip(contextReceivers.lastIndex downTo 0).forEach { (contextReceiverDescriptor, i) -> contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed()
contextReceivers[i].name()?.let { .forEach { (contextReceiverDescriptor, i) ->
receiverToLabelMap[contextReceiverDescriptor] = it contextReceivers[i].name()?.let {
receiverToLabelMap[contextReceiverDescriptor] = it
}
} }
}
trace.record(BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, functionDescriptor, receiverToLabelMap) trace.record(BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, functionDescriptor, receiverToLabelMap)
functionDescriptor.initialize( functionDescriptor.initialize(
extensionReceiver, extensionReceiver,
@@ -66,6 +66,7 @@ import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
import org.jetbrains.kotlin.resolve.constants.*; import org.jetbrains.kotlin.resolve.constants.*;
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind; import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope; 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.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue; import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
@@ -599,7 +600,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
else if (!receivers.isEmpty()) { else if (!receivers.isEmpty()) {
// `this` cannot point to context receiver // `this` cannot point to context receiver
for (ReceiverParameterDescriptor receiver : receivers) { for (ReceiverParameterDescriptor receiver : receivers) {
if (!(receiver.getValue() instanceof ExtensionReceiver) || !((ExtensionReceiver) receiver.getValue()).isContextReceiver()) { if (!(receiver.getValue() instanceof ContextReceiver)) {
result = receiver; result = receiver;
break; break;
} }
@@ -95,11 +95,11 @@ fun StatementGenerator.generateReceiver(ktDefaultElement: KtElement, receiver: R
fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue { fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffset: Int, receiver: ReceiverValue): IntermediateValue {
val irReceiverType = val irReceiverType =
when (receiver) { when (receiver) {
is ExtensionReceiver -> { is ExtensionReceiver ->
val receiverParameters = receiver.declarationDescriptor.extensionReceiverParameter!!.type.toIrType()
receiver.declarationDescriptor.contextReceiverParameters + listOfNotNull(receiver.declarationDescriptor.extensionReceiverParameter) is ContextReceiver -> {
val receiverParameter = receiverParameters.firstOrNull { it.value == receiver } val receiverParameter = receiver.declarationDescriptor.contextReceiverParameters.firstOrNull()
?: receiver.declarationDescriptor.extensionReceiverParameter!! ?: error("Unknown receiver: $receiver")
receiverParameter.type.toIrType() receiverParameter.type.toIrType()
} }
else -> else ->
@@ -142,10 +142,14 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
is ExpressionReceiver -> is ExpressionReceiver ->
generateExpression(receiver.expression) generateExpression(receiver.expression)
is ExtensionReceiver -> { is ExtensionReceiver -> {
val receiverParameters = listOfNotNull(receiver.declarationDescriptor.extensionReceiverParameter) + IrGetValueImpl(
receiver.declarationDescriptor.contextReceiverParameters defaultStartOffset, defaultStartOffset, irReceiverType,
val receiverParameter = receiverParameters.singleOrNull { it.value == receiver } context.symbolTable.referenceValueParameter(receiver.declarationDescriptor.extensionReceiverParameter!!)
?: receiver.declarationDescriptor.extensionReceiverParameter!! )
}
is ContextReceiver -> {
val receiverParameter = receiver.declarationDescriptor.contextReceiverParameters
.single { it.value == receiver }
IrGetValueImpl( IrGetValueImpl(
defaultStartOffset, defaultStartOffset, irReceiverType, defaultStartOffset, defaultStartOffset, irReceiverType,
context.symbolTable.referenceValueParameter(receiverParameter) context.symbolTable.referenceValueParameter(receiverParameter)
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations; import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.*; import org.jetbrains.kotlin.descriptors.impl.*;
import org.jetbrains.kotlin.name.Name; 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.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.types.KotlinType; import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.Variance; import org.jetbrains.kotlin.types.Variance;
@@ -189,18 +190,19 @@ public class DescriptorFactory {
@Nullable KotlinType receiverParameterType, @Nullable KotlinType receiverParameterType,
@NotNull Annotations annotations @NotNull Annotations annotations
) { ) {
return createExtensionReceiverParameterForCallable(owner, receiverParameterType, annotations, false); return receiverParameterType == null
? null
: new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType, null), annotations);
} }
@Nullable @Nullable
public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable( public static ReceiverParameterDescriptor createContextReceiverParameterForCallable(
@NotNull CallableDescriptor owner, @NotNull CallableDescriptor owner,
@Nullable KotlinType receiverParameterType, @Nullable KotlinType receiverParameterType,
@NotNull Annotations annotations, @NotNull Annotations annotations
boolean isContextReceiver
) { ) {
return receiverParameterType == null return receiverParameterType == null
? null ? null
: new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType, null, isContextReceiver), annotations); : new ReceiverParameterDescriptorImpl(owner, new ContextReceiver(owner, receiverParameterType, null), annotations);
} }
} }
@@ -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 }"
}
@@ -35,25 +35,14 @@ import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker;
public class ExtensionReceiver extends AbstractReceiverValue implements ImplicitReceiver { public class ExtensionReceiver extends AbstractReceiverValue implements ImplicitReceiver {
private final CallableDescriptor descriptor; private final CallableDescriptor descriptor;
private final boolean isContextReceiver;
public ExtensionReceiver( public ExtensionReceiver(
@NotNull CallableDescriptor callableDescriptor, @NotNull CallableDescriptor callableDescriptor,
@NotNull KotlinType receiverType, @NotNull KotlinType receiverType,
@Nullable ReceiverValue original @Nullable ReceiverValue original
) {
this(callableDescriptor, receiverType, original, false);
}
public ExtensionReceiver(
@NotNull CallableDescriptor callableDescriptor,
@NotNull KotlinType receiverType,
@Nullable ReceiverValue original,
boolean isContextReceiver
) { ) {
super(receiverType, original); super(receiverType, original);
this.descriptor = callableDescriptor; this.descriptor = callableDescriptor;
this.isContextReceiver = isContextReceiver;
} }
@NotNull @NotNull
@@ -72,8 +61,4 @@ public class ExtensionReceiver extends AbstractReceiverValue implements Implicit
public String toString() { public String toString() {
return getType() + ": Ext {" + descriptor + "}"; return getType() + ": Ext {" + descriptor + "}";
} }
public boolean isContextReceiver() {
return isContextReceiver;
}
} }