[FE] Store receiver labels differently

This commit is contained in:
Anastasiya Shadrina
2021-11-10 16:49:56 +07:00
committed by TeamCityServer
parent 17f24319d0
commit 3900c2a604
5 changed files with 25 additions and 21 deletions
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.resolve; package org.jetbrains.kotlin.resolve;
import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.intellij.openapi.util.Ref; import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import kotlin.Pair; import kotlin.Pair;
@@ -48,7 +49,6 @@ import org.jetbrains.kotlin.util.slicedMap.*;
import java.util.Collection; import java.util.Collection;
import java.util.Collections; import java.util.Collections;
import java.util.Map;
import static org.jetbrains.kotlin.util.slicedMap.RewritePolicy.DO_NOTHING; import static org.jetbrains.kotlin.util.slicedMap.RewritePolicy.DO_NOTHING;
import static org.jetbrains.kotlin.util.slicedMap.Slices.COMPILE_TIME_VALUE_REWRITE_POLICY; import static org.jetbrains.kotlin.util.slicedMap.Slices.COMPILE_TIME_VALUE_REWRITE_POLICY;
@@ -263,7 +263,7 @@ public interface BindingContext {
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS) .setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS)
.build(); .build();
WritableSlice<DeclarationDescriptor, Map<ReceiverParameterDescriptor, String>> DESCRIPTOR_TO_NAMED_RECEIVERS = Slices.createSimpleSlice(); WritableSlice<DeclarationDescriptor, Multimap<String, ReceiverParameterDescriptor>> DESCRIPTOR_TO_NAMED_RECEIVERS = Slices.createSimpleSlice();
WritableSlice<KtReferenceExpression, PsiElement> LABEL_TARGET = Slices.createSimpleSlice(); WritableSlice<KtReferenceExpression, PsiElement> LABEL_TARGET = Slices.createSimpleSlice();
WritableSlice<KtReferenceExpression, Collection<? extends PsiElement>> AMBIGUOUS_LABEL_TARGET = Slices.createSimpleSlice(); WritableSlice<KtReferenceExpression, Collection<? extends PsiElement>> AMBIGUOUS_LABEL_TARGET = Slices.createSimpleSlice();
WritableSlice<ValueParameterDescriptor, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY = Slices.createSimpleSlice(); WritableSlice<ValueParameterDescriptor, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY = Slices.createSimpleSlice();
@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.resolve; package org.jetbrains.kotlin.resolve;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.intellij.openapi.project.Project; import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiElement;
import kotlin.Pair; import kotlin.Pair;
@@ -957,7 +959,7 @@ public class DescriptorResolver {
} }
} }
LinkedHashMap<ReceiverParameterDescriptor, String> receiverToLabelMap = new LinkedHashMap<>(); Multimap<String, ReceiverParameterDescriptor> nameToReceiverMap = HashMultimap.create();
KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference(); KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference();
ReceiverParameterDescriptor receiverDescriptor = null; ReceiverParameterDescriptor receiverDescriptor = null;
@@ -967,13 +969,16 @@ public class DescriptorResolver {
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable( receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER) propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
); );
receiverToLabelMap.put(receiverDescriptor, receiverTypeRef.nameForReceiverLabel()); String receiverName = receiverTypeRef.nameForReceiverLabel();
if (receiverName != null) {
nameToReceiverMap.put(receiverName, receiverDescriptor);
}
} }
List<KtContextReceiver> contextReceivers = variableDeclaration.getContextReceivers(); List<KtContextReceiver> contextReceivers = variableDeclaration.getContextReceivers();
List<ReceiverParameterDescriptor> contextReceiverDescriptors = List<ReceiverParameterDescriptor> contextReceiverDescriptors =
createReceiverDescriptorsForProperty(propertyDescriptor, scopeForDeclarationResolutionWithTypeParameters, trace, createReceiverDescriptorsForProperty(propertyDescriptor, scopeForDeclarationResolutionWithTypeParameters, trace,
contextReceivers, receiverToLabelMap); contextReceivers, nameToReceiverMap);
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor); LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
KotlinType propertyType = propertyInfo.getVariableType(); KotlinType propertyType = propertyInfo.getVariableType();
@@ -1022,7 +1027,7 @@ public class DescriptorResolver {
new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(FIELD), propertyDescriptor), new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(FIELD), propertyDescriptor),
new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(PROPERTY_DELEGATE_FIELD), propertyDescriptor) new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(PROPERTY_DELEGATE_FIELD), propertyDescriptor)
); );
trace.record(DESCRIPTOR_TO_NAMED_RECEIVERS, propertyDescriptor, receiverToLabelMap); trace.record(DESCRIPTOR_TO_NAMED_RECEIVERS, propertyDescriptor, nameToReceiverMap);
trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor); trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor);
return propertyDescriptor; return propertyDescriptor;
} }
@@ -1032,7 +1037,7 @@ public class DescriptorResolver {
@NotNull LexicalScope scopeForResolution, @NotNull LexicalScope scopeForResolution,
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull List<KtContextReceiver> contextReceivers, @NotNull List<KtContextReceiver> contextReceivers,
@NotNull Map<ReceiverParameterDescriptor, String> receiverToLabelMap @NotNull Multimap<String, ReceiverParameterDescriptor> labelNameToReceiverMap
) { ) {
Map<KtContextReceiver, KotlinType> contextReceiversToTypes = new LinkedHashMap<>(); Map<KtContextReceiver, KotlinType> contextReceiversToTypes = new LinkedHashMap<>();
for (KtContextReceiver contextReceiver: contextReceivers) { for (KtContextReceiver contextReceiver: contextReceivers) {
@@ -1051,7 +1056,7 @@ public class DescriptorResolver {
); );
String contextReceiverName = contextReceiver.name(); String contextReceiverName = contextReceiver.name();
if (contextReceiverName != null) { if (contextReceiverName != null) {
receiverToLabelMap.put(receiverDescriptor, contextReceiverName); labelNameToReceiverMap.put(contextReceiverName, receiverDescriptor);
} }
return receiverDescriptor; return receiverDescriptor;
}).collect(Collectors.toList()); }).collect(Collectors.toList());
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import com.google.common.collect.HashMultimap
import com.intellij.openapi.util.ThrowableComputable import com.intellij.openapi.util.ThrowableComputable
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.util.AstLoadingFilter import com.intellij.util.AstLoadingFilter
@@ -242,20 +243,20 @@ class FunctionDescriptorResolver(
} }
if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) { if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
val receiverToLabelMap = linkedMapOf<ReceiverParameterDescriptor, String>() val labelNameToReceiverMap = HashMultimap.create<String, ReceiverParameterDescriptor>()
if (receiverTypeRef != null && extensionReceiver != null) { if (receiverTypeRef != null && extensionReceiver != null) {
receiverTypeRef.nameForReceiverLabel()?.let { receiverTypeRef.nameForReceiverLabel()?.let {
receiverToLabelMap[extensionReceiver] = it labelNameToReceiverMap.put(it, extensionReceiver)
} }
} }
contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed() contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed()
.forEach { (contextReceiverDescriptor, i) -> .forEach { (contextReceiverDescriptor, i) ->
contextReceivers[i].name()?.let { contextReceivers[i].name()?.let {
receiverToLabelMap[contextReceiverDescriptor] = it labelNameToReceiverMap.put(it, contextReceiverDescriptor)
} }
} }
trace.record(BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, functionDescriptor, receiverToLabelMap) trace.record(BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, functionDescriptor, labelNameToReceiverMap)
} }
functionDescriptor.initialize( functionDescriptor.initialize(
@@ -316,13 +316,13 @@ private fun findReceiverByLabelOrGetDefault(
bindingContext: BindingContext, bindingContext: BindingContext,
labelName: String labelName: String
): ReceiverParameterDescriptor { ): ReceiverParameterDescriptor {
val receiverToLabelMap = bindingContext.get( val labelNameToReceiverMap = bindingContext.get(
BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS,
if (descriptorOfThisReceiver is PropertyAccessorDescriptor) descriptorOfThisReceiver.correspondingProperty else descriptorOfThisReceiver if (descriptorOfThisReceiver is PropertyAccessorDescriptor) descriptorOfThisReceiver.correspondingProperty else descriptorOfThisReceiver
) )
return receiverToLabelMap?.entries?.find { return labelNameToReceiverMap?.get(labelName)?.singleOrNull()
it.value == labelName ?: default
}?.key ?: default ?: error("'This' refers to the callable member without a receiver parameter: $descriptorOfThisReceiver") ?: error("'This' refers to the callable member without a receiver parameter: $descriptorOfThisReceiver")
} }
private fun postfix(argumentInfo: IdentifierInfo, op: KtToken): IdentifierInfo = private fun postfix(argumentInfo: IdentifierInfo, op: KtToken): IdentifierInfo =
@@ -183,15 +183,13 @@ object LabelResolver {
) )
val declarationDescriptor = context.trace.bindingContext[DECLARATION_TO_DESCRIPTOR, element] val declarationDescriptor = context.trace.bindingContext[DECLARATION_TO_DESCRIPTOR, element]
if (declarationDescriptor is FunctionDescriptor) { if (declarationDescriptor is FunctionDescriptor) {
val receiverToLabelMap = context.trace.bindingContext[ val labelNameToReceiverMap = context.trace.bindingContext[
DESCRIPTOR_TO_NAMED_RECEIVERS, DESCRIPTOR_TO_NAMED_RECEIVERS,
if (declarationDescriptor is PropertyAccessorDescriptor) declarationDescriptor.correspondingProperty else declarationDescriptor if (declarationDescriptor is PropertyAccessorDescriptor) declarationDescriptor.correspondingProperty else declarationDescriptor
] ]
val thisReceivers = receiverToLabelMap?.entries?.filter { val thisReceivers = labelNameToReceiverMap?.get(labelName.identifier)
it.value == labelName.identifier
}?.map { it.key } ?: emptyList()
val thisReceiver = when { val thisReceiver = when {
thisReceivers.isEmpty() -> declarationDescriptor.extensionReceiverParameter thisReceivers == null -> declarationDescriptor.extensionReceiverParameter
thisReceivers.size == 1 -> thisReceivers.single() thisReceivers.size == 1 -> thisReceivers.single()
else -> { else -> {
BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel) BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel)