From 2f822ab4d999cc9ffe5fa4896163735220362c41 Mon Sep 17 00:00:00 2001 From: Ilya Kirillov Date: Thu, 30 Jun 2022 17:50:30 +0200 Subject: [PATCH] [k1] add information about context receiver labels to ContextClassReceiver/ContextReceiver --- .../kotlin/resolve/DescriptorResolver.java | 2 +- .../resolve/FunctionDescriptorResolver.kt | 31 ++++++++++++++----- .../lazy/descriptors/LazyClassDescriptor.java | 11 ++++--- .../impl/FunctionDescriptorImpl.java | 2 ++ .../impl/PropertyDescriptorImpl.java | 6 +++- .../impl/TypeAliasConstructorDescriptor.kt | 2 ++ .../kotlin/resolve/DescriptorFactory.java | 6 ++-- .../scopes/receivers/ContextClassReceiver.kt | 6 ++-- .../scopes/receivers/ContextReceiver.kt | 6 ++-- .../scopes/receivers/ImplicitReceiver.kt | 6 ++++ .../deserialization/MemberDeserializer.kt | 7 ++++- .../DeserializedClassDescriptor.kt | 7 ++++- 12 files changed, 70 insertions(+), 22 deletions(-) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java index ca80d55c886..76e08ed6d0b 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/DescriptorResolver.java @@ -984,7 +984,7 @@ public class DescriptorResolver { KotlinType type = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeReference, trace, true); AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER)); return DescriptorFactory.createContextReceiverParameterForCallable( - propertyDescriptor, type, splitter.getAnnotationsForTarget(RECEIVER) + propertyDescriptor, type, contextReceiver.labelNameAsName(), splitter.getAnnotationsForTarget(RECEIVER) ); }).collect(Collectors.toList()); diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt index 29bd9a917cf..8e435c65b56 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/FunctionDescriptorResolver.kt @@ -58,7 +58,8 @@ import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope import org.jetbrains.kotlin.resolve.scopes.TraceBasedLocalRedeclarationChecker import org.jetbrains.kotlin.resolve.source.toSourceElement 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.error.ErrorTypeKind 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.isFunctionExpression import org.jetbrains.kotlin.types.expressions.ExpressionTypingUtils.isFunctionLiteral +import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.types.typeUtil.replaceAnnotations import java.util.* @@ -201,8 +203,12 @@ class FunctionDescriptorResolver( val contextReceiverTypes = if (function is KtFunctionLiteral) expectedFunctionType.getContextReceiversTypes() else contextReceivers - .mapNotNull { it.typeReference() } - .map { typeResolver.resolveType(headerScope, it, trace, true) } + .mapNotNull { + val typeReference = it.typeReference() ?: return@mapNotNull null + val type = typeResolver.resolveType(headerScope, typeReference, trace, true) + ContextReceiverTypeWithLabel(type, it.labelNameAsName()) + } + val valueParameterDescriptors = createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession) @@ -234,10 +240,13 @@ class FunctionDescriptorResolver( functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER) ) } - val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { - val splitter = AnnotationSplitter(storageManager, it.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) + val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { contextReceiver -> + val splitter = AnnotationSplitter(storageManager, contextReceiver.type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER)) 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? = if (functionTypeExpected()) this.getReceiverTypeFromFunctionType() else null - private fun KotlinType.getContextReceiversTypes(): List = - if (functionTypeExpected()) this.getContextReceiverTypesFromFunctionType() else emptyList() + private fun KotlinType.getContextReceiversTypes(): List = + if (functionTypeExpected()) { + this.getContextReceiverTypesFromFunctionType().map { ContextReceiverTypeWithLabel(it, label = null)} + } else { + emptyList() + } private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List? = if (functionTypeExpected()) { @@ -514,4 +527,6 @@ class FunctionDescriptorResolver( } return result } + + private data class ContextReceiverTypeWithLabel(val type: KotlinType, val label: Name?) } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java index 075b4d45948..0395618eb50 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/lazy/descriptors/LazyClassDescriptor.java @@ -308,17 +308,20 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes } List contextReceivers = classOrObject.getContextReceivers(); List contextReceiverDescriptors = contextReceivers.stream() - .map(KtContextReceiver::typeReference) - .filter(Objects::nonNull) - .map(typeReference -> { + .map(contextReceiver -> { + KtTypeReference typeReference = contextReceiver.typeReference(); + if (typeReference == null) return null; KotlinType kotlinType = c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true); return DescriptorFactory.createContextReceiverParameterForClass( this, kotlinType, + contextReceiver.labelNameAsName(), Annotations.Companion.getEMPTY() ); - }).collect(Collectors.toList()); + }) + .filter(Objects::nonNull) + .collect(Collectors.toList()); if (c.getLanguageVersionSettings().supportsFeature(LanguageFeature.ContextReceivers)) { HashMultimap labelNameToReceiverMap = HashMultimap.create(); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java index 10819f6ad4e..666dc0aab48 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/FunctionDescriptorImpl.java @@ -15,6 +15,7 @@ import org.jetbrains.kotlin.descriptors.annotations.AnnotationsKt; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.resolve.DescriptorFactory; 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.utils.SmartList; @@ -635,6 +636,7 @@ public abstract class FunctionDescriptorImpl extends DeclarationDescriptorNonRoo } ReceiverParameterDescriptor substitutedContextReceiverParameter = DescriptorFactory.createContextReceiverParameterForCallable(substitutedDescriptor, substitutedContextReceiverType, + ((ImplicitContextReceiver)newContextReceiverParameter.getValue()).getCustomLabelName(), newContextReceiverParameter.getAnnotations()); substitutedContextReceiverParameters.add(substitutedContextReceiverParameter); diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java index 927eb40b604..f623dc21a27 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/PropertyDescriptorImpl.java @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations; 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.ImplicitContextReceiver; import org.jetbrains.kotlin.types.*; import org.jetbrains.kotlin.utils.SmartSet; @@ -561,7 +562,10 @@ public class PropertyDescriptorImpl extends VariableDescriptorWithInitializerImp if (substitutedType == null) return null; return new ReceiverParameterDescriptorImpl( substitutedPropertyDescriptor, - new ContextReceiver(substitutedPropertyDescriptor, substitutedType, receiverParameterDescriptor.getValue()), + new ContextReceiver(substitutedPropertyDescriptor, + substitutedType, + ((ImplicitContextReceiver) receiverParameterDescriptor.getValue()).getCustomLabelName(), + receiverParameterDescriptor.getValue()), receiverParameterDescriptor.getAnnotations() ); } diff --git a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt index 28a221e890a..24cc18c5a6e 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/descriptors/impl/TypeAliasConstructorDescriptor.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.SpecialNames 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.getValue import org.jetbrains.kotlin.types.* @@ -209,6 +210,7 @@ class TypeAliasConstructorDescriptorImpl private constructor( DescriptorFactory.createContextReceiverParameterForClass( classDescriptor, substitutorForUnderlyingClass.safeSubstitute(it.type, Variance.INVARIANT), + (it.value as ImplicitContextReceiver).customLabelName, Annotations.EMPTY ) } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java index f5ac834aab6..aad3aff2d31 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/DescriptorFactory.java @@ -200,21 +200,23 @@ public class DescriptorFactory { public static ReceiverParameterDescriptor createContextReceiverParameterForCallable( @NotNull CallableDescriptor owner, @Nullable KotlinType receiverParameterType, + @Nullable Name customLabelName, @NotNull Annotations annotations ) { return receiverParameterType == null ? null - : new ReceiverParameterDescriptorImpl(owner, new ContextReceiver(owner, receiverParameterType, null), annotations); + : new ReceiverParameterDescriptorImpl(owner, new ContextReceiver(owner, receiverParameterType, customLabelName, null), annotations); } @Nullable public static ReceiverParameterDescriptor createContextReceiverParameterForClass( @NotNull ClassDescriptor owner, @Nullable KotlinType receiverParameterType, + @Nullable Name customLabelName, @NotNull Annotations annotations ) { return receiverParameterType == null ? null - : new ReceiverParameterDescriptorImpl(owner, new ContextClassReceiver(owner, receiverParameterType, null), annotations); + : new ReceiverParameterDescriptorImpl(owner, new ContextClassReceiver(owner, receiverParameterType, customLabelName, null), annotations); } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextClassReceiver.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextClassReceiver.kt index af3c18da28b..6e823ef5665 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextClassReceiver.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextClassReceiver.kt @@ -7,17 +7,19 @@ package org.jetbrains.kotlin.resolve.scopes.receivers import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType class ContextClassReceiver( val classDescriptor: ClassDescriptor, receiverType: KotlinType, + override val customLabelName: Name?, original: ReceiverValue? -): AbstractReceiverValue(receiverType, original), ImplicitReceiver { +): AbstractReceiverValue(receiverType, original), ImplicitContextReceiver { override val declarationDescriptor: DeclarationDescriptor 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 }" } \ No newline at end of file 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 index f8602304ac8..f991c0f121a 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextReceiver.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ContextReceiver.kt @@ -6,14 +6,16 @@ package org.jetbrains.kotlin.resolve.scopes.receivers import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.types.KotlinType class ContextReceiver( override val declarationDescriptor: CallableDescriptor, receiverType: KotlinType, + override val customLabelName: Name?, original: ReceiverValue? -) : AbstractReceiverValue(receiverType, original), ImplicitReceiver { - override fun replaceType(newType: KotlinType): ReceiverValue = ContextReceiver(declarationDescriptor, newType, original) +) : AbstractReceiverValue(receiverType, original), ImplicitContextReceiver { + override fun replaceType(newType: KotlinType): ReceiverValue = ContextReceiver(declarationDescriptor, newType, customLabelName, 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/ImplicitReceiver.kt b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ImplicitReceiver.kt index 2fe3f65737a..acdada22258 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ImplicitReceiver.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/resolve/scopes/receivers/ImplicitReceiver.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.resolve.scopes.receivers import org.jetbrains.kotlin.descriptors.DeclarationDescriptor +import org.jetbrains.kotlin.name.Name /** * Describes an implicit "this" receiver @@ -24,3 +25,8 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor interface ImplicitReceiver : ReceiverValue { val declarationDescriptor: DeclarationDescriptor } + + +interface ImplicitContextReceiver : ImplicitReceiver { + val customLabelName: Name? +} diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt index 2bba9f9b2e4..640669d8afc 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/MemberDeserializer.kt @@ -358,6 +358,11 @@ class MemberDeserializer(private val c: DeserializationContext) { callableDescriptor: CallableDescriptor ): ReceiverParameterDescriptor? { 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 + ) } } diff --git a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt index 5a5f00088ab..628c6daf873 100644 --- a/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt +++ b/core/deserialization/src/org/jetbrains/kotlin/serialization/deserialization/descriptors/DeserializedClassDescriptor.kt @@ -150,7 +150,12 @@ class DeserializedClassDescriptor( val contextReceiverType = c.typeDeserializer.type(it) ReceiverParameterDescriptorImpl( thisAsReceiverParameter, - ContextClassReceiver(this, contextReceiverType, null), + ContextClassReceiver( + this, + contextReceiverType, + /* customLabelName = */ null/*todo store custom label name in metadata?*/, + null + ), Annotations.EMPTY ); }