[k1] add information about context receiver labels to ContextClassReceiver/ContextReceiver

This commit is contained in:
Ilya Kirillov
2022-06-30 17:50:30 +02:00
parent c1ec1d9d4c
commit 2f822ab4d9
12 changed files with 70 additions and 22 deletions
@@ -984,7 +984,7 @@ public class DescriptorResolver {
KotlinType type = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeReference, trace, true); KotlinType type = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeReference, trace, true);
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER)); AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER));
return DescriptorFactory.createContextReceiverParameterForCallable( return DescriptorFactory.createContextReceiverParameterForCallable(
propertyDescriptor, type, splitter.getAnnotationsForTarget(RECEIVER) propertyDescriptor, type, contextReceiver.labelNameAsName(), splitter.getAnnotationsForTarget(RECEIVER)
); );
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@@ -58,7 +58,8 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope
import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker
import org.jetbrains.kotlin.resolve.source.toSourceElement import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.checker.KotlinTypeChecker import org.jetbrains.kotlin.types.checker.KotlinTypeChecker
import org.jetbrains.kotlin.types.error.ErrorTypeKind import org.jetbrains.kotlin.types.error.ErrorTypeKind
import org.jetbrains.kotlin.types.error.ErrorUtils import org.jetbrains.kotlin.types.error.ErrorUtils
@@ -66,6 +67,7 @@ import org.jetbrains.kotlin.types.expressions.ExpressionTypingServices
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionExpression
import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations
import java.util.* import java.util.*
@@ -201,8 +203,12 @@ class FunctionDescriptorResolver(
val contextReceiverTypes = val contextReceiverTypes =
if (function is KtFunctionLiteral) expectedFunctionType.getContextReceiversTypes() if (function is KtFunctionLiteral) expectedFunctionType.getContextReceiversTypes()
else contextReceivers else contextReceivers
.mapNotNull { it.typeReference() } .mapNotNull {
.map { typeResolver.resolveType(headerScope, it, trace, true) } val typeReference = it.typeReference() ?: return@mapNotNull null
val type = typeResolver.resolveType(headerScope, typeReference, trace, true)
ContextReceiverTypeWithLabel(type, it.labelNameAsName())
}
val valueParameterDescriptors = val valueParameterDescriptors =
createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession) createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession)
@@ -234,10 +240,13 @@ class FunctionDescriptorResolver(
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER) functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
) )
} }
val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { contextReceiver ->
val splitter = AnnotationSplitter(storageManager, it.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) val splitter = AnnotationSplitter(storageManager, contextReceiver.type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
DescriptorFactory.createContextReceiverParameterForCallable( DescriptorFactory.createContextReceiverParameterForCallable(
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER) functionDescriptor,
contextReceiver.type,
contextReceiver.label,
splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER),
) )
} }
@@ -358,8 +367,12 @@ class FunctionDescriptorResolver(
private fun KotlinType.getReceiverType(): KotlinType? = private fun KotlinType.getReceiverType(): KotlinType? =
if (functionTypeExpected()) this.getReceiverTypeFromFunctionType() else null if (functionTypeExpected()) this.getReceiverTypeFromFunctionType() else null
private fun KotlinType.getContextReceiversTypes(): List<KotlinType> = private fun KotlinType.getContextReceiversTypes(): List<ContextReceiverTypeWithLabel> =
if (functionTypeExpected()) this.getContextReceiverTypesFromFunctionType() else emptyList() if (functionTypeExpected()) {
this.getContextReceiverTypesFromFunctionType().map { ContextReceiverTypeWithLabel(it, label = null)}
} else {
emptyList()
}
private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? = private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
if (functionTypeExpected()) { if (functionTypeExpected()) {
@@ -514,4 +527,6 @@ class FunctionDescriptorResolver(
} }
return result return result
} }
private data class ContextReceiverTypeWithLabel(val type: KotlinType, val label: Name?)
} }
@@ -308,17 +308,20 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
} }
List<KtContextReceiver> contextReceivers = classOrObject.getContextReceivers(); List<KtContextReceiver> contextReceivers = classOrObject.getContextReceivers();
List<ReceiverParameterDescriptor> contextReceiverDescriptors = contextReceivers.stream() List<ReceiverParameterDescriptor> contextReceiverDescriptors = contextReceivers.stream()
.map(KtContextReceiver::typeReference) .map(contextReceiver -> {
.filter(Objects::nonNull) KtTypeReference typeReference = contextReceiver.typeReference();
.map(typeReference -> { if (typeReference == null) return null;
KotlinType kotlinType = KotlinType kotlinType =
c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true); c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true);
return DescriptorFactory.createContextReceiverParameterForClass( return DescriptorFactory.createContextReceiverParameterForClass(
this, this,
kotlinType, kotlinType,
contextReceiver.labelNameAsName(),
Annotations.Companion.getEMPTY() Annotations.Companion.getEMPTY()
); );
}).collect(Collectors.toList()); })
.filter(Objects::nonNull)
.collect(Collectors.toList());
if (c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ContextReceivers)) { if (c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ContextReceivers)) {
HashMultimap<String, ReceiverParameterDescriptor> labelNameToReceiverMap = HashMultimap.create(); HashMultimap<String, ReceiverParameterDescriptor> labelNameToReceiverMap = HashMultimap.create();
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationsKt;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.DescriptorFactory; import org.jetbrains.kotlin.resolve.DescriptorFactory;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitContextReceiver;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.utils.SmartList; import org.jetbrains.kotlin.utils.SmartList;
@@ -635,6 +636,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo
} }
ReceiverParameterDescriptor substitutedContextReceiverParameter = ReceiverParameterDescriptor substitutedContextReceiverParameter =
DescriptorFactory.createContextReceiverParameterForCallable(substitutedDescriptor, substitutedContextReceiverType, DescriptorFactory.createContextReceiverParameterForCallable(substitutedDescriptor, substitutedContextReceiverType,
((ImplicitContextReceiver)newContextReceiverParameter.getValue()).getCustomLabelName(),
newContextReceiverParameter.getAnnotations()); newContextReceiverParameter.getAnnotations());
substitutedContextReceiverParameters.add(substitutedContextReceiverParameter); substitutedContextReceiverParameters.add(substitutedContextReceiverParameter);
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
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.ContextReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver; import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitContextReceiver;
import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.utils.SmartSet; import org.jetbrains.kotlin.utils.SmartSet;
@@ -561,7 +562,10 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp
if (substitutedType == null) return null; if (substitutedType == null) return null;
return new ReceiverParameterDescriptorImpl( return new ReceiverParameterDescriptorImpl(
substitutedPropertyDescriptor, substitutedPropertyDescriptor,
new ContextReceiver(substitutedPropertyDescriptor, substitutedType, receiverParameterDescriptor.getValue()), new ContextReceiver(substitutedPropertyDescriptor,
substitutedType,
((ImplicitContextReceiver) receiverParameterDescriptor.getValue()).getCustomLabelName(),
receiverParameterDescriptor.getValue()),
receiverParameterDescriptor.getAnnotations() receiverParameterDescriptor.getAnnotations()
); );
} }
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.DescriptorFactory import org.jetbrains.kotlin.resolve.DescriptorFactory
import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitContextReceiver
import org.jetbrains.kotlin.storage.StorageManager import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.* import org.jetbrains.kotlin.types.*
@@ -209,6 +210,7 @@ class TypeAliasConstructorDescriptorImpl private constructor(
DescriptorFactory.createContextReceiverParameterForClass( DescriptorFactory.createContextReceiverParameterForClass(
classDescriptor, classDescriptor,
substitutorForUnderlyingClass.safeSubstitute(it.type, Variance.INVARIANT), substitutorForUnderlyingClass.safeSubstitute(it.type, Variance.INVARIANT),
(it.value as ImplicitContextReceiver).customLabelName,
Annotations.EMPTY Annotations.EMPTY
) )
} }
@@ -200,21 +200,23 @@ public class DescriptorFactory {
public static ReceiverParameterDescriptor createContextReceiverParameterForCallable( public static ReceiverParameterDescriptor createContextReceiverParameterForCallable(
@NotNull CallableDescriptor owner, @NotNull CallableDescriptor owner,
@Nullable KotlinType receiverParameterType, @Nullable KotlinType receiverParameterType,
@Nullable Name customLabelName,
@NotNull Annotations annotations @NotNull Annotations annotations
) { ) {
return receiverParameterType == null return receiverParameterType == null
? null ? null
: new ReceiverParameterDescriptorImpl(owner, new ContextReceiver(owner, receiverParameterType, null), annotations); : new ReceiverParameterDescriptorImpl(owner, new ContextReceiver(owner, receiverParameterType, customLabelName, null), annotations);
} }
@Nullable @Nullable
public static ReceiverParameterDescriptor createContextReceiverParameterForClass( public static ReceiverParameterDescriptor createContextReceiverParameterForClass(
@NotNull ClassDescriptor owner, @NotNull ClassDescriptor owner,
@Nullable KotlinType receiverParameterType, @Nullable KotlinType receiverParameterType,
@Nullable Name customLabelName,
@NotNull Annotations annotations @NotNull Annotations annotations
) { ) {
return receiverParameterType == null return receiverParameterType == null
? null ? null
: new ReceiverParameterDescriptorImpl(owner, new ContextClassReceiver(owner, receiverParameterType, null), annotations); : new ReceiverParameterDescriptorImpl(owner, new ContextClassReceiver(owner, receiverParameterType, customLabelName, null), annotations);
} }
} }
@@ -7,17 +7,19 @@ package org.jetbrains.kotlin.resolve.scopes.receivers
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
class ContextClassReceiver( class ContextClassReceiver(
val classDescriptor: ClassDescriptor, val classDescriptor: ClassDescriptor,
receiverType: KotlinType, receiverType: KotlinType,
override val customLabelName: Name?,
original: ReceiverValue? original: ReceiverValue?
): AbstractReceiverValue(receiverType, original), ImplicitReceiver { ): AbstractReceiverValue(receiverType, original), ImplicitContextReceiver {
override val declarationDescriptor: DeclarationDescriptor override val declarationDescriptor: DeclarationDescriptor
get() = classDescriptor get() = classDescriptor
override fun replaceType(newType: KotlinType): ReceiverValue = ContextClassReceiver(classDescriptor, newType, original) override fun replaceType(newType: KotlinType): ReceiverValue = ContextClassReceiver(classDescriptor, newType, customLabelName, original)
override fun toString(): String = "$type: Ctx { $classDescriptor }" override fun toString(): String = "$type: Ctx { $classDescriptor }"
} }
@@ -6,14 +6,16 @@
package org.jetbrains.kotlin.resolve.scopes.receivers package org.jetbrains.kotlin.resolve.scopes.receivers
import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
class ContextReceiver( class ContextReceiver(
override val declarationDescriptor: CallableDescriptor, override val declarationDescriptor: CallableDescriptor,
receiverType: KotlinType, receiverType: KotlinType,
override val customLabelName: Name?,
original: ReceiverValue? original: ReceiverValue?
) : AbstractReceiverValue(receiverType, original), ImplicitReceiver { ) : AbstractReceiverValue(receiverType, original), ImplicitContextReceiver {
override fun replaceType(newType: KotlinType): ReceiverValue = ContextReceiver(declarationDescriptor, newType, original) override fun replaceType(newType: KotlinType): ReceiverValue = ContextReceiver(declarationDescriptor, newType, customLabelName, original)
override fun toString(): String = "Cxt { $declarationDescriptor }" override fun toString(): String = "Cxt { $declarationDescriptor }"
} }
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.scopes.receivers package org.jetbrains.kotlin.resolve.scopes.receivers
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.name.Name
/** /**
* Describes an implicit "this" receiver * Describes an implicit "this" receiver
@@ -24,3 +25,8 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
interface ImplicitReceiver : ReceiverValue { interface ImplicitReceiver : ReceiverValue {
val declarationDescriptor: DeclarationDescriptor val declarationDescriptor: DeclarationDescriptor
} }
interface ImplicitContextReceiver : ImplicitReceiver {
val customLabelName: Name?
}
@@ -358,6 +358,11 @@ class MemberDeserializer(private val c: DeserializationContext) {
callableDescriptor: CallableDescriptor callableDescriptor: CallableDescriptor
): ReceiverParameterDescriptor? { ): ReceiverParameterDescriptor? {
val contextReceiverType = deserializationContext.typeDeserializer.type(this) val contextReceiverType = deserializationContext.typeDeserializer.type(this)
return DescriptorFactory.createContextReceiverParameterForCallable(callableDescriptor, contextReceiverType, Annotations.EMPTY) return DescriptorFactory.createContextReceiverParameterForCallable(
callableDescriptor,
contextReceiverType,
/* customLabelName = */ null/*todo store custom label name in metadata?*/,
Annotations.EMPTY
)
} }
} }
@@ -150,7 +150,12 @@ class DeserializedClassDescriptor(
val contextReceiverType = c.typeDeserializer.type(it) val contextReceiverType = c.typeDeserializer.type(it)
ReceiverParameterDescriptorImpl( ReceiverParameterDescriptorImpl(
thisAsReceiverParameter, thisAsReceiverParameter,
ContextClassReceiver(this, contextReceiverType, null), ContextClassReceiver(
this,
contextReceiverType,
/* customLabelName = */ null/*todo store custom label name in metadata?*/,
null
),
Annotations.EMPTY Annotations.EMPTY
); );
} }