[FE] Store receiver labels differently
This commit is contained in:
committed by
TeamCityServer
parent
17f24319d0
commit
3900c2a604
@@ -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(
|
||||||
|
|||||||
+4
-4
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user