[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;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Multimap;
import com.intellij.openapi.util.Ref;
import com.intellij.psi.PsiElement;
import kotlin.Pair;
@@ -48,7 +49,6 @@ import org.jetbrains.kotlin.util.slicedMap.*;
import java.util.Collection;
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.Slices.COMPILE_TIME_VALUE_REWRITE_POLICY;
@@ -263,7 +263,7 @@ public interface BindingContext {
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS)
.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, Collection<? extends PsiElement>> AMBIGUOUS_LABEL_TARGET = Slices.createSimpleSlice();
WritableSlice<ValueParameterDescriptor, PropertyDescriptor> VALUE_PARAMETER_AS_PROPERTY = Slices.createSimpleSlice();
@@ -16,7 +16,9 @@
package org.jetbrains.kotlin.resolve;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.intellij.openapi.project.Project;
import com.intellij.psi.PsiElement;
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();
ReceiverParameterDescriptor receiverDescriptor = null;
@@ -967,13 +969,16 @@ public class DescriptorResolver {
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
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<ReceiverParameterDescriptor> contextReceiverDescriptors =
createReceiverDescriptorsForProperty(propertyDescriptor, scopeForDeclarationResolutionWithTypeParameters, trace,
contextReceivers, receiverToLabelMap);
contextReceivers, nameToReceiverMap);
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
KotlinType propertyType = propertyInfo.getVariableType();
@@ -1022,7 +1027,7 @@ public class DescriptorResolver {
new FieldDescriptorImpl(annotationSplitter.getAnnotationsForTarget(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);
return propertyDescriptor;
}
@@ -1032,7 +1037,7 @@ public class DescriptorResolver {
@NotNull LexicalScope scopeForResolution,
@NotNull BindingTrace trace,
@NotNull List<KtContextReceiver> contextReceivers,
@NotNull Map<ReceiverParameterDescriptor, String> receiverToLabelMap
@NotNull Multimap<String, ReceiverParameterDescriptor> labelNameToReceiverMap
) {
Map<KtContextReceiver, KotlinType> contextReceiversToTypes = new LinkedHashMap<>();
for (KtContextReceiver contextReceiver: contextReceivers) {
@@ -1051,7 +1056,7 @@ public class DescriptorResolver {
);
String contextReceiverName = contextReceiver.name();
if (contextReceiverName != null) {
receiverToLabelMap.put(receiverDescriptor, contextReceiverName);
labelNameToReceiverMap.put(contextReceiverName, receiverDescriptor);
}
return receiverDescriptor;
}).collect(Collectors.toList());
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.resolve
import com.google.common.collect.HashMultimap
import com.intellij.openapi.util.ThrowableComputable
import com.intellij.psi.PsiElement
import com.intellij.util.AstLoadingFilter
@@ -242,20 +243,20 @@ class FunctionDescriptorResolver(
}
if (languageVersionSettings.supportsFeature(LanguageFeature.ContextReceivers)) {
val receiverToLabelMap = linkedMapOf<ReceiverParameterDescriptor, String>()
val labelNameToReceiverMap = HashMultimap.create<String, ReceiverParameterDescriptor>()
if (receiverTypeRef != null && extensionReceiver != null) {
receiverTypeRef.nameForReceiverLabel()?.let {
receiverToLabelMap[extensionReceiver] = it
labelNameToReceiverMap.put(it, extensionReceiver)
}
}
contextReceiverDescriptors.zip(0 until contextReceivers.size).reversed()
.forEach { (contextReceiverDescriptor, i) ->
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(
@@ -316,13 +316,13 @@ private fun findReceiverByLabelOrGetDefault(
bindingContext: BindingContext,
labelName: String
): ReceiverParameterDescriptor {
val receiverToLabelMap = bindingContext.get(
val labelNameToReceiverMap = bindingContext.get(
BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS,
if (descriptorOfThisReceiver is PropertyAccessorDescriptor) descriptorOfThisReceiver.correspondingProperty else descriptorOfThisReceiver
)
return receiverToLabelMap?.entries?.find {
it.value == labelName
}?.key ?: default ?: error("'This' refers to the callable member without a receiver parameter: $descriptorOfThisReceiver")
return labelNameToReceiverMap?.get(labelName)?.singleOrNull()
?: default
?: error("'This' refers to the callable member without a receiver parameter: $descriptorOfThisReceiver")
}
private fun postfix(argumentInfo: IdentifierInfo, op: KtToken): IdentifierInfo =
@@ -183,15 +183,13 @@ object LabelResolver {
)
val declarationDescriptor = context.trace.bindingContext[DECLARATION_TO_DESCRIPTOR, element]
if (declarationDescriptor is FunctionDescriptor) {
val receiverToLabelMap = context.trace.bindingContext[
val labelNameToReceiverMap = context.trace.bindingContext[
DESCRIPTOR_TO_NAMED_RECEIVERS,
if (declarationDescriptor is PropertyAccessorDescriptor) declarationDescriptor.correspondingProperty else declarationDescriptor
]
val thisReceivers = receiverToLabelMap?.entries?.filter {
it.value == labelName.identifier
}?.map { it.key } ?: emptyList()
val thisReceivers = labelNameToReceiverMap?.get(labelName.identifier)
val thisReceiver = when {
thisReceivers.isEmpty() -> declarationDescriptor.extensionReceiverParameter
thisReceivers == null -> declarationDescriptor.extensionReceiverParameter
thisReceivers.size == 1 -> thisReceivers.single()
else -> {
BindingContextUtils.reportAmbiguousLabel(context.trace, targetLabel, declarationsByLabel)