[PSI, FE, PSI2IR] Use labels for referencing specific receiver
This commit is contained in:
committed by
TeamCityServer
parent
aaabf5e1ca
commit
1bcaeabd84
+3
-3
@@ -437,9 +437,9 @@ fun getDeclarationLabels(lambdaOrFun: PsiElement?, descriptor: DeclarationDescri
|
|||||||
val result = HashSet<String>()
|
val result = HashSet<String>()
|
||||||
|
|
||||||
if (lambdaOrFun != null) {
|
if (lambdaOrFun != null) {
|
||||||
val label = LabelResolver.getLabelNameIfAny(lambdaOrFun)
|
val label = LabelResolver.getLabelNamesIfAny(lambdaOrFun, addContextReceiverNames = false)
|
||||||
if (label != null) {
|
if (label.isNotEmpty()) {
|
||||||
result.add(label.asString())
|
result.add(label.single().asString())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+36
@@ -10624,6 +10624,42 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/plusMatrix.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/plusMatrix.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("superWithContext.kt")
|
||||||
|
public void testSuperWithContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/superWithContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisIdentifierInfo.kt")
|
||||||
|
public void testThisIdentifierInfo() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisIdentifierInfo.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithCustomLabel.kt")
|
||||||
|
public void testThisWithCustomLabel() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithCustomLabel.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithReceiverLabelsClasses.kt")
|
||||||
|
public void testThisWithReceiverLabelsClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsClasses.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithReceiverLabelsFunctions.kt")
|
||||||
|
public void testThisWithReceiverLabelsFunctions() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsFunctions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithReceiverLabelsProperties.kt")
|
||||||
|
public void testThisWithReceiverLabelsProperties() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeParameterized.kt")
|
@TestMetadata("typeParameterized.kt")
|
||||||
public void testTypeParameterized() throws Exception {
|
public void testTypeParameterized() throws Exception {
|
||||||
|
|||||||
+6
@@ -16168,6 +16168,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
|||||||
public void testSimpleCall() throws Exception {
|
public void testSimpleCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/simpleCall.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/simpleCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("this.kt")
|
||||||
|
public void testThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/this.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -167,7 +167,7 @@ class SyntheticClassOrObjectDescriptor(
|
|||||||
override fun getPrimaryConstructorModifierList(): KtModifierList? = null
|
override fun getPrimaryConstructorModifierList(): KtModifierList? = null
|
||||||
override fun getPrimaryConstructorParameters(): List<KtParameter> = emptyList()
|
override fun getPrimaryConstructorParameters(): List<KtParameter> = emptyList()
|
||||||
override fun getSecondaryConstructors(): List<KtSecondaryConstructor> = emptyList()
|
override fun getSecondaryConstructors(): List<KtSecondaryConstructor> = emptyList()
|
||||||
override fun getContextReceiverTypeReferences(): List<KtTypeReference> = emptyList()
|
override fun getContextReceivers(): List<KtContextReceiver> = emptyList()
|
||||||
|
|
||||||
override fun getPsiOrParent() = _parent.psiOrParent
|
override fun getPsiOrParent() = _parent.psiOrParent
|
||||||
override fun getParent() = _parent.psiOrParent
|
override fun getParent() = _parent.psiOrParent
|
||||||
|
|||||||
@@ -48,6 +48,8 @@ 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.LinkedHashMap;
|
||||||
|
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;
|
||||||
@@ -262,6 +264,7 @@ public interface BindingContext {
|
|||||||
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS)
|
.setFurtherLookupSlices(DECLARATIONS_TO_DESCRIPTORS)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
WritableSlice<DeclarationDescriptor, LinkedHashMap<ReceiverParameterDescriptor, String>> 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();
|
||||||
|
|||||||
@@ -1023,7 +1023,8 @@ public class BodyResolver {
|
|||||||
);
|
);
|
||||||
|
|
||||||
// Synthetic "field" creation
|
// Synthetic "field" creation
|
||||||
if (functionDescriptor instanceof PropertyAccessorDescriptor && functionDescriptor.getExtensionReceiverParameter() == null) {
|
if (functionDescriptor instanceof PropertyAccessorDescriptor && functionDescriptor.getExtensionReceiverParameter() == null
|
||||||
|
&& functionDescriptor.getContextReceiverParameters().isEmpty()) {
|
||||||
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) functionDescriptor;
|
PropertyAccessorDescriptor accessorDescriptor = (PropertyAccessorDescriptor) functionDescriptor;
|
||||||
KtProperty property = (KtProperty) function.getParent();
|
KtProperty property = (KtProperty) function.getParent();
|
||||||
SourceElement propertySourceElement = KotlinSourceElementKt.toSourceElement(property);
|
SourceElement propertySourceElement = KotlinSourceElementKt.toSourceElement(property);
|
||||||
|
|||||||
@@ -64,13 +64,11 @@ import org.jetbrains.kotlin.types.typeUtil.TypeUtilsKt;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
import static org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget.*;
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
import static org.jetbrains.kotlin.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.kotlin.lexer.KtTokens.*;
|
import static org.jetbrains.kotlin.lexer.KtTokens.*;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.CONSTRUCTOR;
|
import static org.jetbrains.kotlin.resolve.BindingContext.*;
|
||||||
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE_ALIAS;
|
|
||||||
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
import static org.jetbrains.kotlin.resolve.DescriptorUtils.*;
|
||||||
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveMemberModalityFromModifiers;
|
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveMemberModalityFromModifiers;
|
||||||
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers;
|
import static org.jetbrains.kotlin.resolve.ModifiersChecker.resolveVisibilityFromModifiers;
|
||||||
@@ -929,7 +927,6 @@ public class DescriptorResolver {
|
|||||||
LexicalScope scopeForDeclarationResolutionWithTypeParameters;
|
LexicalScope scopeForDeclarationResolutionWithTypeParameters;
|
||||||
LexicalScope scopeForInitializerResolutionWithTypeParameters;
|
LexicalScope scopeForInitializerResolutionWithTypeParameters;
|
||||||
KotlinType receiverType = null;
|
KotlinType receiverType = null;
|
||||||
Stream<KotlinType> contextReceiverTypes;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
List<KtTypeParameter> typeParameters = variableDeclaration.getTypeParameters();
|
List<KtTypeParameter> typeParameters = variableDeclaration.getTypeParameters();
|
||||||
@@ -958,37 +955,25 @@ public class DescriptorResolver {
|
|||||||
scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
|
scopeForDeclarationResolutionWithTypeParameters = writableScopeForDeclarationResolution;
|
||||||
scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
|
scopeForInitializerResolutionWithTypeParameters = writableScopeForInitializerResolution;
|
||||||
}
|
}
|
||||||
|
|
||||||
KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference();
|
|
||||||
if (receiverTypeRef != null) {
|
|
||||||
receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
List<KtTypeReference> contextReceiverTypeRefs = variableDeclaration.getContextReceiverTypeReferences();
|
|
||||||
for (KtTypeReference contextReceiverTypeRef: contextReceiverTypeRefs) {
|
|
||||||
typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, contextReceiverTypeRef, trace, true);
|
|
||||||
}
|
|
||||||
contextReceiverTypes = contextReceiverTypeRefs.stream()
|
|
||||||
.map((typeRef) -> typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, typeRef, trace, true));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ReceiverParameterDescriptor receiverDescriptor;
|
LinkedHashMap<ReceiverParameterDescriptor, String> receiverToLabelMap = new LinkedHashMap<>();
|
||||||
if (receiverType != null) {
|
|
||||||
|
KtTypeReference receiverTypeRef = variableDeclaration.getReceiverTypeReference();
|
||||||
|
ReceiverParameterDescriptor receiverDescriptor = null;
|
||||||
|
if (receiverTypeRef != null) {
|
||||||
|
receiverType = typeResolver.resolveType(scopeForDeclarationResolutionWithTypeParameters, receiverTypeRef, trace, true);
|
||||||
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
|
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
|
||||||
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
|
receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||||
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER)
|
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER),
|
||||||
);
|
false);
|
||||||
}
|
receiverToLabelMap.put(receiverDescriptor, receiverTypeRef.nameForReceiverLabel());
|
||||||
else {
|
|
||||||
receiverDescriptor = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<ReceiverParameterDescriptor> contextReceiverDescriptors = contextReceiverTypes.map((type) -> {
|
List<KtContextReceiver> contextReceivers = variableDeclaration.getContextReceivers();
|
||||||
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, type.getAnnotations(), EnumSet.of(RECEIVER));
|
List<ReceiverParameterDescriptor> contextReceiverDescriptors =
|
||||||
return DescriptorFactory.createExtensionReceiverParameterForCallable(
|
createReceiverDescriptorsForProperty(propertyDescriptor, scopeForDeclarationResolutionWithTypeParameters, trace,
|
||||||
propertyDescriptor, type, splitter.getAnnotationsForTarget(RECEIVER)
|
contextReceivers, receiverToLabelMap);
|
||||||
);
|
|
||||||
}).collect(Collectors.toList());
|
|
||||||
|
|
||||||
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
|
LexicalScope scopeForInitializer = ScopeUtils.makeScopeForPropertyInitializer(scopeForInitializerResolutionWithTypeParameters, propertyDescriptor);
|
||||||
KotlinType propertyType = propertyInfo.getVariableType();
|
KotlinType propertyType = propertyInfo.getVariableType();
|
||||||
@@ -1037,11 +1022,41 @@ 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(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor);
|
trace.record(BindingContext.VARIABLE, variableDeclaration, propertyDescriptor);
|
||||||
return propertyDescriptor;
|
return propertyDescriptor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ReceiverParameterDescriptor> createReceiverDescriptorsForProperty(
|
||||||
|
@NotNull PropertyDescriptor propertyDescriptor,
|
||||||
|
@NotNull LexicalScope scopeForResolution,
|
||||||
|
@NotNull BindingTrace trace,
|
||||||
|
@NotNull List<KtContextReceiver> contextReceivers,
|
||||||
|
@NotNull Map<ReceiverParameterDescriptor, String> receiverToLabelMap
|
||||||
|
) {
|
||||||
|
Map<KtContextReceiver, KotlinType> contextReceiversToTypes = new LinkedHashMap<>();
|
||||||
|
for (KtContextReceiver contextReceiver: contextReceivers) {
|
||||||
|
KtTypeReference typeReference = contextReceiver.typeReference();
|
||||||
|
if (typeReference == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
KotlinType kotlinType = typeResolver.resolveType(scopeForResolution, typeReference, trace, true);
|
||||||
|
contextReceiversToTypes.put(contextReceiver, kotlinType);
|
||||||
|
}
|
||||||
|
return Lists.reverse(contextReceivers).stream().map(contextReceiver -> {
|
||||||
|
KotlinType receiverType = contextReceiversToTypes.get(contextReceiver);
|
||||||
|
AnnotationSplitter splitter = new AnnotationSplitter(storageManager, receiverType.getAnnotations(), EnumSet.of(RECEIVER));
|
||||||
|
ReceiverParameterDescriptor receiverDescriptor = DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||||
|
propertyDescriptor, receiverType, splitter.getAnnotationsForTarget(RECEIVER),
|
||||||
|
true);
|
||||||
|
String contextReceiverName = contextReceiver.name();
|
||||||
|
if (contextReceiverName != null) {
|
||||||
|
receiverToLabelMap.put(receiverDescriptor, contextReceiverName);
|
||||||
|
}
|
||||||
|
return receiverDescriptor;
|
||||||
|
}).collect(Collectors.toList());
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
/*package*/ static KotlinType transformAnonymousTypeIfNeeded(
|
/*package*/ static KotlinType transformAnonymousTypeIfNeeded(
|
||||||
@NotNull DeclarationDescriptorWithVisibility descriptor,
|
@NotNull DeclarationDescriptorWithVisibility descriptor,
|
||||||
|
|||||||
@@ -197,7 +197,8 @@ class FunctionDescriptorResolver(
|
|||||||
if (function is KtFunctionLiteral) expectedFunctionType.getReceiverType() else null
|
if (function is KtFunctionLiteral) expectedFunctionType.getReceiverType() else null
|
||||||
}
|
}
|
||||||
|
|
||||||
val contextReceiverTypes = function.contextReceiverTypeReferences.map {
|
val contextReceivers = function.contextReceivers
|
||||||
|
val contextReceiverTypes = contextReceivers.mapNotNull { it.typeReference() }.map {
|
||||||
typeResolver.resolveType(headerScope, it, trace, true)
|
typeResolver.resolveType(headerScope, it, trace, true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -225,23 +226,35 @@ class FunctionDescriptorResolver(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val receiverToLabelMap = linkedMapOf<ReceiverParameterDescriptor, String>()
|
||||||
val extensionReceiver = receiverType?.let {
|
val extensionReceiver = receiverType?.let {
|
||||||
val splitter = AnnotationSplitter(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
|
val splitter = AnnotationSplitter(storageManager, receiverType.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
|
||||||
DescriptorFactory.createExtensionReceiverParameterForCallable(
|
DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||||
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
|
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER), false
|
||||||
)
|
|
||||||
}
|
|
||||||
val contextReceivers = contextReceiverTypes.map {
|
|
||||||
val splitter = AnnotationSplitter(storageManager, it.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
|
|
||||||
DescriptorFactory.createExtensionReceiverParameterForCallable(
|
|
||||||
functionDescriptor, it, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER)
|
|
||||||
)
|
)
|
||||||
|
}?.apply {
|
||||||
|
val extensionReceiverName = receiverTypeRef?.nameForReceiverLabel()
|
||||||
|
if (extensionReceiverName != null) {
|
||||||
|
receiverToLabelMap[this] = extensionReceiverName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val contextReceiverDescriptors = contextReceiverTypes.mapNotNull { type ->
|
||||||
|
val splitter = AnnotationSplitter(storageManager, type.annotations, EnumSet.of(AnnotationUseSiteTarget.RECEIVER))
|
||||||
|
DescriptorFactory.createExtensionReceiverParameterForCallable(
|
||||||
|
functionDescriptor, type, splitter.getAnnotationsForTarget(AnnotationUseSiteTarget.RECEIVER), true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
contextReceiverDescriptors.reversed().zip(contextReceivers.lastIndex downTo 0).forEach { (contextReceiverDescriptor, i) ->
|
||||||
|
contextReceivers[i].name()?.let {
|
||||||
|
receiverToLabelMap[contextReceiverDescriptor] = it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trace.record(BindingContext.DESCRIPTOR_TO_NAMED_RECEIVERS, functionDescriptor, receiverToLabelMap)
|
||||||
functionDescriptor.initialize(
|
functionDescriptor.initialize(
|
||||||
extensionReceiver,
|
extensionReceiver,
|
||||||
getDispatchReceiverParameterIfNeeded(container),
|
getDispatchReceiverParameterIfNeeded(container),
|
||||||
contextReceivers,
|
contextReceiverDescriptors,
|
||||||
typeParameterDescriptors,
|
typeParameterDescriptors,
|
||||||
valueParameterDescriptors,
|
valueParameterDescriptors,
|
||||||
returnType,
|
returnType,
|
||||||
|
|||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.resolve;
|
package org.jetbrains.kotlin.resolve;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
import kotlin.Unit;
|
import kotlin.Unit;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.kotlin.descriptors.*;
|
import org.jetbrains.kotlin.descriptors.*;
|
||||||
@@ -73,7 +74,9 @@ public class FunctionDescriptorUtil {
|
|||||||
}
|
}
|
||||||
List<ReceiverParameterDescriptor> contextReceiverParameters = descriptor.getContextReceiverParameters();
|
List<ReceiverParameterDescriptor> contextReceiverParameters = descriptor.getContextReceiverParameters();
|
||||||
if (!contextReceiverParameters.isEmpty()) {
|
if (!contextReceiverParameters.isEmpty()) {
|
||||||
implicitReceivers.addAll(contextReceiverParameters);
|
implicitReceivers.addAll(
|
||||||
|
Lists.reverse(contextReceiverParameters)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return new LexicalScopeImpl(
|
return new LexicalScopeImpl(
|
||||||
outerScope, descriptor, true, implicitReceivers,
|
outerScope, descriptor, true, implicitReceivers,
|
||||||
|
|||||||
+44
-12
@@ -180,7 +180,7 @@ internal fun getIdForStableIdentifier(
|
|||||||
|
|
||||||
is KtThisExpression -> {
|
is KtThisExpression -> {
|
||||||
val declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.instanceReference)
|
val declarationDescriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, expression.instanceReference)
|
||||||
getIdForThisReceiver(declarationDescriptor)
|
getIdForThisReceiver(declarationDescriptor, bindingContext, expression.getLabelName())
|
||||||
}
|
}
|
||||||
|
|
||||||
is KtPostfixExpression -> {
|
is KtPostfixExpression -> {
|
||||||
@@ -229,7 +229,7 @@ private fun getIdForSimpleNameExpression(
|
|||||||
if (implicitReceiver == null) {
|
if (implicitReceiver == null) {
|
||||||
selectorInfo
|
selectorInfo
|
||||||
} else {
|
} else {
|
||||||
val receiverInfo = getIdForImplicitReceiver(implicitReceiver, simpleNameExpression)
|
val receiverInfo = getIdForImplicitReceiver(implicitReceiver, simpleNameExpression, bindingContext)
|
||||||
|
|
||||||
if (receiverInfo == null) {
|
if (receiverInfo == null) {
|
||||||
selectorInfo
|
selectorInfo
|
||||||
@@ -255,9 +255,9 @@ private fun getIdForSimpleNameExpression(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIdForImplicitReceiver(receiverValue: ReceiverValue?, expression: KtExpression?) =
|
private fun getIdForImplicitReceiver(receiverValue: ReceiverValue?, expression: KtExpression?, bindingContext: BindingContext) =
|
||||||
when (receiverValue) {
|
when (receiverValue) {
|
||||||
is ImplicitReceiver -> getIdForThisReceiver(receiverValue.declarationDescriptor)
|
is ImplicitReceiver -> getIdForThisReceiver(receiverValue.declarationDescriptor, bindingContext)
|
||||||
|
|
||||||
is TransientReceiver ->
|
is TransientReceiver ->
|
||||||
throw AssertionError("Transient receiver is implicit for an explicit expression: $expression. Receiver: $receiverValue")
|
throw AssertionError("Transient receiver is implicit for an explicit expression: $expression. Receiver: $receiverValue")
|
||||||
@@ -265,16 +265,48 @@ private fun getIdForImplicitReceiver(receiverValue: ReceiverValue?, expression:
|
|||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getIdForThisReceiver(descriptorOfThisReceiver: DeclarationDescriptor?) = when (descriptorOfThisReceiver) {
|
private fun getIdForThisReceiver(
|
||||||
is CallableDescriptor -> {
|
descriptorOfThisReceiver: DeclarationDescriptor?,
|
||||||
val receiverParameter = descriptorOfThisReceiver.extensionReceiverParameter
|
bindingContext: BindingContext,
|
||||||
?: error("'This' refers to the callable member without a receiver parameter: $descriptorOfThisReceiver")
|
labelName: String? = null
|
||||||
IdentifierInfo.Receiver(receiverParameter.value)
|
) =
|
||||||
|
when (descriptorOfThisReceiver) {
|
||||||
|
is CallableDescriptor -> {
|
||||||
|
val receiverParameter = findReceiverByLabelOrGetDefault(
|
||||||
|
descriptorOfThisReceiver,
|
||||||
|
descriptorOfThisReceiver.extensionReceiverParameter,
|
||||||
|
bindingContext,
|
||||||
|
labelName
|
||||||
|
)
|
||||||
|
IdentifierInfo.Receiver(receiverParameter.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
is ClassDescriptor -> {
|
||||||
|
val receiverParameter = findReceiverByLabelOrGetDefault(
|
||||||
|
descriptorOfThisReceiver,
|
||||||
|
descriptorOfThisReceiver.thisAsReceiverParameter,
|
||||||
|
bindingContext,
|
||||||
|
labelName
|
||||||
|
)
|
||||||
|
IdentifierInfo.Receiver(receiverParameter.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> IdentifierInfo.NO
|
||||||
}
|
}
|
||||||
|
|
||||||
is ClassDescriptor -> IdentifierInfo.Receiver(descriptorOfThisReceiver.thisAsReceiverParameter.value)
|
private fun findReceiverByLabelOrGetDefault(
|
||||||
|
descriptorOfThisReceiver: DeclarationDescriptor,
|
||||||
else -> IdentifierInfo.NO
|
default: ReceiverParameterDescriptor?,
|
||||||
|
bindingContext: BindingContext,
|
||||||
|
labelName: String? = null
|
||||||
|
): ReceiverParameterDescriptor {
|
||||||
|
val receiverToLabelMap = 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")
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun postfix(argumentInfo: IdentifierInfo, op: KtToken): IdentifierInfo =
|
private fun postfix(argumentInfo: IdentifierInfo, op: KtToken): IdentifierInfo =
|
||||||
|
|||||||
+12
-11
@@ -49,10 +49,7 @@ import org.jetbrains.kotlin.storage.StorageManager;
|
|||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
|
import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.*;
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static kotlin.collections.CollectionsKt.firstOrNull;
|
import static kotlin.collections.CollectionsKt.firstOrNull;
|
||||||
@@ -308,13 +305,17 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
if (classOrObject == null) {
|
if (classOrObject == null) {
|
||||||
return CollectionsKt.emptyList();
|
return CollectionsKt.emptyList();
|
||||||
}
|
}
|
||||||
return classOrObject.getContextReceiverTypeReferences().stream().map(typeReference -> {
|
return classOrObject.getContextReceivers().stream()
|
||||||
KotlinType kotlinType = c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true);
|
.map(KtContextReceiver::typeReference)
|
||||||
return new ReceiverParameterDescriptorImpl(
|
.filter(Objects::nonNull)
|
||||||
this,
|
.map(typeReference -> {
|
||||||
new ExtensionClassReceiver(this, kotlinType, null),
|
KotlinType kotlinType =
|
||||||
Annotations.Companion.getEMPTY()
|
c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true);
|
||||||
);
|
return new ReceiverParameterDescriptorImpl(
|
||||||
|
this,
|
||||||
|
new ExtensionClassReceiver(this, kotlinType, null),
|
||||||
|
Annotations.Companion.getEMPTY()
|
||||||
|
);
|
||||||
}).collect(Collectors.toList());
|
}).collect(Collectors.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-1
@@ -67,6 +67,7 @@ import org.jetbrains.kotlin.resolve.constants.*;
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScopeKind;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
|
import org.jetbrains.kotlin.resolve.scopes.LexicalWritableScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionReceiver;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
|
import org.jetbrains.kotlin.resolve.scopes.utils.ScopeUtilsKt;
|
||||||
import org.jetbrains.kotlin.types.*;
|
import org.jetbrains.kotlin.types.*;
|
||||||
@@ -596,7 +597,13 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (!receivers.isEmpty()) {
|
else if (!receivers.isEmpty()) {
|
||||||
result = receivers.get(0);
|
// `this` cannot point to context receiver
|
||||||
|
for (ReceiverParameterDescriptor receiver : receivers) {
|
||||||
|
if (!(receiver.getValue() instanceof ExtensionReceiver) || !((ExtensionReceiver) receiver.getValue()).isContextReceiver()) {
|
||||||
|
result = receiver;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (result != null) {
|
if (result != null) {
|
||||||
context.trace.record(REFERENCE_TARGET, expression.getInstanceReference(), result.getContainingDeclaration());
|
context.trace.record(REFERENCE_TARGET, expression.getInstanceReference(), result.getContainingDeclaration());
|
||||||
|
|||||||
@@ -17,28 +17,29 @@
|
|||||||
package org.jetbrains.kotlin.types.expressions
|
package org.jetbrains.kotlin.types.expressions
|
||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
|
||||||
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
|
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.LABEL_NAME_CLASH
|
import org.jetbrains.kotlin.diagnostics.Errors.LABEL_NAME_CLASH
|
||||||
import org.jetbrains.kotlin.diagnostics.Errors.UNRESOLVED_REFERENCE
|
import org.jetbrains.kotlin.diagnostics.Errors.UNRESOLVED_REFERENCE
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
|
import org.jetbrains.kotlin.psi.psiUtil.checkReservedYield
|
||||||
import org.jetbrains.kotlin.resolve.*
|
import org.jetbrains.kotlin.resolve.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.LABEL_TARGET
|
import org.jetbrains.kotlin.resolve.BindingContext.*
|
||||||
import org.jetbrains.kotlin.resolve.BindingContext.REFERENCE_TARGET
|
|
||||||
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
import org.jetbrains.kotlin.resolve.calls.context.ResolutionContext
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.getDeclarationsByLabel
|
import org.jetbrains.kotlin.resolve.scopes.utils.getDeclarationsByLabel
|
||||||
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
|
|
||||||
object LabelResolver {
|
object LabelResolver {
|
||||||
private fun getElementsByLabelName(labelName: Name, labelExpression: KtSimpleNameExpression): Set<KtElement> {
|
private fun getElementsByLabelName(
|
||||||
|
labelName: Name,
|
||||||
|
labelExpression: KtSimpleNameExpression,
|
||||||
|
isThisExpression: Boolean
|
||||||
|
): Set<KtElement> {
|
||||||
val elements = linkedSetOf<KtElement>()
|
val elements = linkedSetOf<KtElement>()
|
||||||
var parent: PsiElement? = labelExpression.parent
|
var parent: PsiElement? = labelExpression.parent
|
||||||
while (parent != null) {
|
while (parent != null) {
|
||||||
val name = getLabelNameIfAny(parent)
|
val names = getLabelNamesIfAny(parent, isThisExpression)
|
||||||
if (name != null && name == labelName) {
|
if (names.contains(labelName)) {
|
||||||
elements.add(getExpressionUnderLabel(parent as KtExpression))
|
elements.add(getExpressionUnderLabel(parent as KtExpression))
|
||||||
}
|
}
|
||||||
parent = if (parent is KtCodeFragment) parent.context else parent.parent
|
parent = if (parent is KtCodeFragment) parent.context else parent.parent
|
||||||
@@ -46,20 +47,33 @@ object LabelResolver {
|
|||||||
return elements
|
return elements
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getLabelNameIfAny(element: PsiElement): Name? {
|
fun getLabelNamesIfAny(element: PsiElement, addContextReceiverNames: Boolean): List<Name> {
|
||||||
return when (element) {
|
val result = mutableListOf<Name>()
|
||||||
is KtLabeledExpression -> element.getLabelNameAsName()
|
when (element) {
|
||||||
is KtFunctionLiteral -> getLabelNameIfAny(element.parent)
|
is KtLabeledExpression -> result.addIfNotNull(element.getLabelNameAsName())
|
||||||
is KtLambdaExpression -> getLabelForFunctionalExpression(element)
|
// TODO: Support context receivers in function literals
|
||||||
is KtNamedFunction -> element.nameAsName ?: getLabelForFunctionalExpression(element)
|
is KtFunctionLiteral -> return getLabelNamesIfAny(element.parent, false)
|
||||||
else -> null
|
is KtLambdaExpression -> result.addIfNotNull(getLabelForFunctionalExpression(element))
|
||||||
}
|
}
|
||||||
|
val functionOrProperty = when (element) {
|
||||||
|
is KtNamedFunction -> element
|
||||||
|
is KtPropertyAccessor -> element.property
|
||||||
|
else -> return result
|
||||||
|
}
|
||||||
|
if (addContextReceiverNames) {
|
||||||
|
functionOrProperty.contextReceivers
|
||||||
|
.mapNotNullTo(result) { it.name()?.let { s -> Name.identifier(s) } }
|
||||||
|
functionOrProperty.receiverTypeReference?.nameForReceiverLabel()?.let { result.add(Name.identifier(it)) }
|
||||||
|
}
|
||||||
|
val name = functionOrProperty.nameAsName ?: getLabelForFunctionalExpression(functionOrProperty)
|
||||||
|
result.addIfNotNull(name)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getLabelForFunctionalExpression(element: KtExpression): Name? {
|
private fun getLabelForFunctionalExpression(element: KtExpression): Name? {
|
||||||
val parent = element.parent
|
val parent = element.parent
|
||||||
return when (parent) {
|
return when (parent) {
|
||||||
is KtLabeledExpression -> getLabelNameIfAny(parent)
|
is KtLabeledExpression -> getLabelNamesIfAny(parent, false).singleOrNull()
|
||||||
is KtBinaryExpression -> parent.operationReference.getReferencedNameAsName()
|
is KtBinaryExpression -> parent.operationReference.getReferencedNameAsName()
|
||||||
else -> getCallerName(element)
|
else -> getCallerName(element)
|
||||||
}
|
}
|
||||||
@@ -105,7 +119,7 @@ object LabelResolver {
|
|||||||
val labelName = expression.getLabelNameAsName()
|
val labelName = expression.getLabelNameAsName()
|
||||||
if (labelElement == null || labelName == null) return null
|
if (labelElement == null || labelName == null) return null
|
||||||
|
|
||||||
return resolveNamedLabel(labelName, labelElement, context.trace) ?: run {
|
return resolveNamedLabel(labelName, labelElement, context.trace, false) ?: run {
|
||||||
context.trace.report(UNRESOLVED_REFERENCE.on(labelElement, labelElement))
|
context.trace.report(UNRESOLVED_REFERENCE.on(labelElement, labelElement))
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@@ -114,9 +128,10 @@ object LabelResolver {
|
|||||||
private fun resolveNamedLabel(
|
private fun resolveNamedLabel(
|
||||||
labelName: Name,
|
labelName: Name,
|
||||||
labelExpression: KtSimpleNameExpression,
|
labelExpression: KtSimpleNameExpression,
|
||||||
trace: BindingTrace
|
trace: BindingTrace,
|
||||||
|
isThisExpression: Boolean
|
||||||
): KtElement? {
|
): KtElement? {
|
||||||
val list = getElementsByLabelName(labelName, labelExpression)
|
val list = getElementsByLabelName(labelName, labelExpression, isThisExpression)
|
||||||
if (list.isEmpty()) return null
|
if (list.isEmpty()) return null
|
||||||
|
|
||||||
if (list.size > 1) {
|
if (list.size > 1) {
|
||||||
@@ -160,10 +175,14 @@ object LabelResolver {
|
|||||||
return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver)
|
return LabeledReceiverResolutionResult.labelResolutionSuccess(thisReceiver)
|
||||||
}
|
}
|
||||||
0 -> {
|
0 -> {
|
||||||
val element = resolveNamedLabel(labelName, targetLabel, context.trace)
|
val element = resolveNamedLabel(labelName, targetLabel, context.trace, expression is KtThisExpression)
|
||||||
val declarationDescriptor = context.trace.bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, element]
|
val declarationDescriptor = context.trace.bindingContext[DECLARATION_TO_DESCRIPTOR, element]
|
||||||
if (declarationDescriptor is FunctionDescriptor) {
|
if (declarationDescriptor is FunctionDescriptor) {
|
||||||
val thisReceiver = declarationDescriptor.extensionReceiverParameter
|
val receiverToLabelMap =
|
||||||
|
context.trace.bindingContext[DESCRIPTOR_TO_NAMED_RECEIVERS, if (declarationDescriptor is PropertyAccessorDescriptor) declarationDescriptor.correspondingProperty else declarationDescriptor]
|
||||||
|
val thisReceiver = receiverToLabelMap?.entries?.find {
|
||||||
|
it.value == labelName.identifier
|
||||||
|
}?.key ?: declarationDescriptor.extensionReceiverParameter
|
||||||
if (thisReceiver != null) {
|
if (thisReceiver != null) {
|
||||||
context.trace.record(LABEL_TARGET, targetLabel, element)
|
context.trace.record(LABEL_TARGET, targetLabel, element)
|
||||||
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
context.trace.record(REFERENCE_TARGET, referenceExpression, declarationDescriptor)
|
||||||
|
|||||||
+4
-4
@@ -50,7 +50,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
declareSimpleFunction(
|
declareSimpleFunction(
|
||||||
ktFunction,
|
ktFunction,
|
||||||
ktFunction.receiverTypeReference,
|
ktFunction.receiverTypeReference,
|
||||||
ktFunction.contextReceiverTypeReferences,
|
ktFunction.contextReceivers.mapNotNull { it.typeReference() },
|
||||||
origin,
|
origin,
|
||||||
getOrFail(BindingContext.FUNCTION, ktFunction)
|
getOrFail(BindingContext.FUNCTION, ktFunction)
|
||||||
) {
|
) {
|
||||||
@@ -127,7 +127,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
|
irAccessor.returnType = irAccessor.descriptor.returnType!!.toIrType()
|
||||||
generateValueParameterDeclarations(
|
generateValueParameterDeclarations(
|
||||||
irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference,
|
irAccessor, ktAccessor ?: ktProperty, ktProperty.receiverTypeReference,
|
||||||
ktProperty.contextReceiverTypeReferences
|
ktProperty.contextReceivers.mapNotNull { it.typeReference() }
|
||||||
)
|
)
|
||||||
val ktBodyExpression = ktAccessor?.bodyExpression
|
val ktBodyExpression = ktAccessor?.bodyExpression
|
||||||
irAccessor.body =
|
irAccessor.body =
|
||||||
@@ -237,7 +237,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
declareConstructor(
|
declareConstructor(
|
||||||
ktClassOrObject,
|
ktClassOrObject,
|
||||||
ktClassOrObject.primaryConstructor ?: ktClassOrObject,
|
ktClassOrObject.primaryConstructor ?: ktClassOrObject,
|
||||||
ktClassOrObject.contextReceiverTypeReferences,
|
ktClassOrObject.contextReceivers.mapNotNull { it.typeReference() },
|
||||||
primaryConstructorDescriptor
|
primaryConstructorDescriptor
|
||||||
) { irConstructor ->
|
) { irConstructor ->
|
||||||
if (
|
if (
|
||||||
@@ -254,7 +254,7 @@ class FunctionGenerator(declarationGenerator: DeclarationGenerator) : Declaratio
|
|||||||
return declareConstructor(
|
return declareConstructor(
|
||||||
ktConstructor,
|
ktConstructor,
|
||||||
ktConstructor,
|
ktConstructor,
|
||||||
ktClassOrObject.contextReceiverTypeReferences,
|
ktClassOrObject.contextReceivers.mapNotNull { it.typeReference() },
|
||||||
constructorDescriptor
|
constructorDescriptor
|
||||||
) {
|
) {
|
||||||
when {
|
when {
|
||||||
|
|||||||
+8
-4
@@ -422,12 +422,16 @@ class StatementGenerator(
|
|||||||
generateThisReceiver(startOffset, endOffset, referenceTarget.thisAsReceiverParameter.type, referenceTarget)
|
generateThisReceiver(startOffset, endOffset, referenceTarget.thisAsReceiverParameter.type, referenceTarget)
|
||||||
|
|
||||||
is CallableDescriptor -> {
|
is CallableDescriptor -> {
|
||||||
val extensionReceiver = referenceTarget.extensionReceiverParameter ?: TODO("No extension receiver: $referenceTarget")
|
val resolvedCall = getResolvedCall(expression)
|
||||||
val extensionReceiverType = extensionReceiver.type.toIrType()
|
val receivers = listOfNotNull(referenceTarget.extensionReceiverParameter) + referenceTarget.contextReceiverParameters
|
||||||
|
val receiver = receivers.find {
|
||||||
|
it == resolvedCall?.candidateDescriptor
|
||||||
|
} ?: referenceTarget.extensionReceiverParameter ?: TODO("No receiver: $referenceTarget")
|
||||||
|
val receiverType = receiver.type.toIrType()
|
||||||
IrGetValueImpl(
|
IrGetValueImpl(
|
||||||
startOffset, endOffset,
|
startOffset, endOffset,
|
||||||
extensionReceiverType,
|
receiverType,
|
||||||
context.symbolTable.referenceValueParameter(extensionReceiver)
|
context.symbolTable.referenceValueParameter(receiver)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ public interface KtNodeTypes {
|
|||||||
IElementType SECONDARY_CONSTRUCTOR = KtStubElementTypes.SECONDARY_CONSTRUCTOR;
|
IElementType SECONDARY_CONSTRUCTOR = KtStubElementTypes.SECONDARY_CONSTRUCTOR;
|
||||||
IElementType PRIMARY_CONSTRUCTOR = KtStubElementTypes.PRIMARY_CONSTRUCTOR;
|
IElementType PRIMARY_CONSTRUCTOR = KtStubElementTypes.PRIMARY_CONSTRUCTOR;
|
||||||
IElementType CONTEXT_RECEIVER = KtStubElementTypes.CONTEXT_RECEIVER;
|
IElementType CONTEXT_RECEIVER = KtStubElementTypes.CONTEXT_RECEIVER;
|
||||||
|
IElementType CONTEXT_RECEIVER_LIST = KtStubElementTypes.CONTEXT_RECEIVER_LIST;
|
||||||
|
|
||||||
IElementType TYPE_PARAMETER_LIST = KtStubElementTypes.TYPE_PARAMETER_LIST;
|
IElementType TYPE_PARAMETER_LIST = KtStubElementTypes.TYPE_PARAMETER_LIST;
|
||||||
IElementType TYPE_PARAMETER = KtStubElementTypes.TYPE_PARAMETER;
|
IElementType TYPE_PARAMETER = KtStubElementTypes.TYPE_PARAMETER;
|
||||||
|
|||||||
@@ -597,7 +597,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isAtLabelDefinitionOrMissingIdentifier() {
|
boolean isAtLabelDefinitionOrMissingIdentifier() {
|
||||||
return (at(IDENTIFIER) && myBuilder.rawLookup(1) == AT) || at(AT);
|
return (at(IDENTIFIER) && myBuilder.rawLookup(1) == AT) || at(AT);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1690,7 +1690,7 @@ public class KotlinExpressionParsing extends AbstractKotlinParsing {
|
|||||||
/*
|
/*
|
||||||
* IDENTIFIER "@"
|
* IDENTIFIER "@"
|
||||||
*/
|
*/
|
||||||
private void parseLabelDefinition() {
|
void parseLabelDefinition() {
|
||||||
PsiBuilder.Marker labelWrap = mark();
|
PsiBuilder.Marker labelWrap = mark();
|
||||||
PsiBuilder.Marker mark = mark();
|
PsiBuilder.Marker mark = mark();
|
||||||
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ public interface KtCallableDeclaration extends KtNamedDeclaration, KtTypeParamet
|
|||||||
KtTypeReference getReceiverTypeReference();
|
KtTypeReference getReceiverTypeReference();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
List<KtTypeReference> getContextReceiverTypeReferences();
|
List<KtContextReceiver> getContextReceivers();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
KtTypeReference getTypeReference();
|
KtTypeReference getTypeReference();
|
||||||
|
|||||||
@@ -188,17 +188,17 @@ abstract class KtClassOrObject :
|
|||||||
return parts.joinToString(separator = ".")
|
return parts.joinToString(separator = ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getContextReceiverTypeReferences(): List<KtTypeReference> {
|
override fun getContextReceivers(): List<KtContextReceiver> {
|
||||||
val stub = stub
|
val stub = stub
|
||||||
if (stub != null) {
|
if (stub != null) {
|
||||||
return getStubOrPsiChildrenAsList(KtStubElementTypes.TYPE_REFERENCE)
|
return getStubOrPsiChildrenAsList(KtStubElementTypes.CONTEXT_RECEIVER)
|
||||||
}
|
}
|
||||||
var node = node.firstChildNode
|
var node = node.firstChildNode
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
val tt = node.elementType
|
val tt = node.elementType
|
||||||
if (tt === KtNodeTypes.CONTEXT_RECEIVER) {
|
if (tt === KtNodeTypes.CONTEXT_RECEIVER_LIST) {
|
||||||
val contextReceiver = node.psi as KtContextReceiver
|
val contextReceiver = node.psi as KtContextReceiverList
|
||||||
return contextReceiver.typeReferences()
|
return contextReceiver.contextReceivers()
|
||||||
}
|
}
|
||||||
node = node.treeNext
|
node = node.treeNext
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ abstract class KtConstructor<T : KtConstructor<T>> : KtDeclarationStub<KotlinPla
|
|||||||
|
|
||||||
override fun getReceiverTypeReference() = null
|
override fun getReceiverTypeReference() = null
|
||||||
|
|
||||||
override fun getContextReceiverTypeReferences(): List<KtTypeReference> = emptyList()
|
override fun getContextReceivers(): List<KtContextReceiver> = emptyList()
|
||||||
|
|
||||||
override fun getTypeReference() = null
|
override fun getTypeReference() = null
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.psi
|
|||||||
|
|
||||||
import com.intellij.lang.ASTNode
|
import com.intellij.lang.ASTNode
|
||||||
import org.jetbrains.kotlin.KtNodeTypes
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
|
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
|
||||||
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||||
|
|
||||||
@@ -14,9 +15,14 @@ class KtContextReceiver : KtElementImplStub<KotlinPlaceHolderStub<KtContextRecei
|
|||||||
constructor(node: ASTNode) : super(node)
|
constructor(node: ASTNode) : super(node)
|
||||||
constructor(stub: KotlinPlaceHolderStub<KtContextReceiver>) : super(stub, KtStubElementTypes.CONTEXT_RECEIVER)
|
constructor(stub: KotlinPlaceHolderStub<KtContextReceiver>) : super(stub, KtStubElementTypes.CONTEXT_RECEIVER)
|
||||||
|
|
||||||
override fun <R : Any?, D : Any?> accept(visitor: KtVisitor<R, D>, data: D): R {
|
fun targetLabel(): KtSimpleNameExpression? =
|
||||||
return visitor.visitContextReceiver(this, data)
|
findChildByType<KtContainerNode?>(KtNodeTypes.LABEL_QUALIFIER)
|
||||||
}
|
?.findChildByType(KtNodeTypes.LABEL)
|
||||||
|
|
||||||
fun typeReferences(): List<KtTypeReference> = findChildrenByType(KtNodeTypes.TYPE_REFERENCE)
|
fun labelName(): String? = targetLabel()?.getReferencedName()
|
||||||
|
fun labelNameAsName(): Name? = targetLabel()?.getReferencedNameAsName()
|
||||||
|
|
||||||
|
fun typeReference(): KtTypeReference? = findChildByType(KtNodeTypes.TYPE_REFERENCE)
|
||||||
|
|
||||||
|
fun name(): String? = labelName() ?: typeReference()?.nameForReceiverLabel()
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,25 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.psi
|
||||||
|
|
||||||
|
import com.intellij.lang.ASTNode
|
||||||
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.KotlinPlaceHolderStub
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.elements.KtStubElementTypes
|
||||||
|
|
||||||
|
class KtContextReceiverList : KtElementImplStub<KotlinPlaceHolderStub<KtContextReceiverList>> {
|
||||||
|
constructor(node: ASTNode) : super(node)
|
||||||
|
constructor(stub: KotlinPlaceHolderStub<KtContextReceiverList>) : super(stub, KtStubElementTypes.CONTEXT_RECEIVER_LIST)
|
||||||
|
|
||||||
|
override fun <R : Any?, D : Any?> accept(visitor: KtVisitor<R, D>, data: D): R {
|
||||||
|
return visitor.visitContextReceiverList(this, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun contextReceivers(): List<KtContextReceiver> = findChildrenByType(KtNodeTypes.CONTEXT_RECEIVER)
|
||||||
|
|
||||||
|
fun typeReferences(): List<KtTypeReference> = contextReceivers().mapNotNull { it.typeReference() }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -77,7 +77,7 @@ public class KtDestructuringDeclarationEntry extends KtNamedDeclarationNotStubbe
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<KtTypeReference> getContextReceiverTypeReferences() {
|
public List<KtContextReceiver> getContextReceivers() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ public abstract class KtFunctionNotStubbed extends KtTypeParameterListOwnerNotSt
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<KtTypeReference> getContextReceiverTypeReferences() {
|
public List<KtContextReceiver> getContextReceivers() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -185,12 +185,12 @@ public class KtNamedFunction extends KtTypeParameterListOwnerStub<KotlinFunction
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<KtTypeReference> getContextReceiverTypeReferences() {
|
public List<KtContextReceiver> getContextReceivers() {
|
||||||
KotlinFunctionStub stub = getStub();
|
KotlinFunctionStub stub = getStub();
|
||||||
if (stub != null) {
|
if (stub != null) {
|
||||||
List<KtContextReceiver> childContextReceivers = getStubOrPsiChildrenAsList(KtStubElementTypes.CONTEXT_RECEIVER);
|
List<KtContextReceiverList> childContextReceivers = getStubOrPsiChildrenAsList(KtStubElementTypes.CONTEXT_RECEIVER_LIST);
|
||||||
if (!childContextReceivers.isEmpty()) {
|
if (!childContextReceivers.isEmpty()) {
|
||||||
return childContextReceivers.get(0).typeReferences();
|
return childContextReceivers.get(0).contextReceivers();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
@@ -200,13 +200,13 @@ public class KtNamedFunction extends KtTypeParameterListOwnerStub<KotlinFunction
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<KtTypeReference> getContextReceiverTypeRefsByTree() {
|
private List<KtContextReceiver> getContextReceiverTypeRefsByTree() {
|
||||||
PsiElement child = getFirstChild();
|
PsiElement child = getFirstChild();
|
||||||
while (child != null) {
|
while (child != null) {
|
||||||
IElementType tt = child.getNode().getElementType();
|
IElementType tt = child.getNode().getElementType();
|
||||||
if (tt == KtTokens.LPAR || tt == KtTokens.COLON) break;
|
if (tt == KtTokens.LPAR || tt == KtTokens.COLON) break;
|
||||||
if (child instanceof KtContextReceiver) {
|
if (child instanceof KtContextReceiverList) {
|
||||||
return ((KtContextReceiver) child).typeReferences();
|
return ((KtContextReceiverList) child).contextReceivers();
|
||||||
}
|
}
|
||||||
child = child.getNextSibling();
|
child = child.getNextSibling();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -195,7 +195,7 @@ public class KtParameter extends KtNamedDeclarationStub<KotlinParameterStub> imp
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<KtTypeReference> getContextReceiverTypeReferences() {
|
public List<KtContextReceiver> getContextReceivers() {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,12 +116,12 @@ public class KtProperty extends KtTypeParameterListOwnerStub<KotlinPropertyStub>
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public List<KtTypeReference> getContextReceiverTypeReferences() {
|
public List<KtContextReceiver> getContextReceivers() {
|
||||||
KotlinPropertyStub stub = getStub();
|
KotlinPropertyStub stub = getStub();
|
||||||
if (stub != null) {
|
if (stub != null) {
|
||||||
KtContextReceiver contextReceiver = getStubOrPsiChild(KtStubElementTypes.CONTEXT_RECEIVER);
|
KtContextReceiverList contextReceiver = getStubOrPsiChild(KtStubElementTypes.CONTEXT_RECEIVER_LIST);
|
||||||
if (contextReceiver != null) {
|
if (contextReceiver != null) {
|
||||||
return contextReceiver.typeReferences();
|
return contextReceiver.contextReceivers();
|
||||||
} else {
|
} else {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
@@ -130,16 +130,16 @@ public class KtProperty extends KtTypeParameterListOwnerStub<KotlinPropertyStub>
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private List<KtTypeReference> getContextReceiverTypeRefsByTree() {
|
private List<KtContextReceiver> getContextReceiverTypeRefsByTree() {
|
||||||
ASTNode node = getNode().getFirstChildNode();
|
ASTNode node = getNode().getFirstChildNode();
|
||||||
while (node != null) {
|
while (node != null) {
|
||||||
IElementType tt = node.getElementType();
|
IElementType tt = node.getElementType();
|
||||||
if (tt == KtTokens.COLON) {
|
if (tt == KtTokens.COLON) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (tt == KtNodeTypes.CONTEXT_RECEIVER) {
|
if (tt == KtNodeTypes.CONTEXT_RECEIVER_LIST) {
|
||||||
KtContextReceiver contextReceiver = (KtContextReceiver) node.getPsi();
|
KtContextReceiverList contextReceiver = (KtContextReceiverList) node.getPsi();
|
||||||
return contextReceiver.typeReferences();
|
return contextReceiver.contextReceivers();
|
||||||
}
|
}
|
||||||
node = node.getTreeNext();
|
node = node.getTreeNext();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ public interface KtPureClassOrObject extends KtPureElement, KtDeclarationContain
|
|||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@ReadOnly
|
@ReadOnly
|
||||||
List<KtTypeReference> getContextReceiverTypeReferences();
|
List<KtContextReceiver> getContextReceivers();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
KtClassBody getBody();
|
KtClassBody getBody();
|
||||||
|
|||||||
@@ -55,4 +55,6 @@ class KtTypeReference : KtModifierListOwnerStub<KotlinPlaceHolderStub<KtTypeRefe
|
|||||||
fun hasParentheses(): Boolean {
|
fun hasParentheses(): Boolean {
|
||||||
return findChildByType<PsiElement>(KtTokens.LPAR) != null && findChildByType<PsiElement>(KtTokens.RPAR) != null
|
return findChildByType<PsiElement>(KtTokens.LPAR) != null && findChildByType<PsiElement>(KtTokens.RPAR) != null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun nameForReceiverLabel() = (typeElement as? KtUserType)?.referencedName
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -158,8 +158,8 @@ public class KtVisitor<R, D> extends PsiElementVisitor {
|
|||||||
return visitSuperTypeListEntry(specifier, data);
|
return visitSuperTypeListEntry(specifier, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public R visitContextReceiver(@NotNull KtContextReceiver contextReceiver, D data) {
|
public R visitContextReceiverList(@NotNull KtContextReceiverList contextReceiverList, D data) {
|
||||||
return visitKtElement(contextReceiver, data);
|
return visitKtElement(contextReceiverList, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public R visitConstructorDelegationCall(@NotNull KtConstructorDelegationCall call, D data) {
|
public R visitConstructorDelegationCall(@NotNull KtConstructorDelegationCall call, D data) {
|
||||||
|
|||||||
@@ -145,6 +145,8 @@ public interface KtStubElementTypes {
|
|||||||
|
|
||||||
KtPlaceHolderStubElementType<KtContextReceiver> CONTEXT_RECEIVER =
|
KtPlaceHolderStubElementType<KtContextReceiver> CONTEXT_RECEIVER =
|
||||||
new KtPlaceHolderStubElementType<>("CONTEXT_RECEIVER", KtContextReceiver.class);
|
new KtPlaceHolderStubElementType<>("CONTEXT_RECEIVER", KtContextReceiver.class);
|
||||||
|
KtPlaceHolderStubElementType<KtContextReceiverList> CONTEXT_RECEIVER_LIST =
|
||||||
|
new KtPlaceHolderStubElementType<>("CONTEXT_RECEIVER_LIST", KtContextReceiverList.class);
|
||||||
|
|
||||||
KtConstantExpressionElementType NULL = new KtConstantExpressionElementType("NULL");
|
KtConstantExpressionElementType NULL = new KtConstantExpressionElementType("NULL");
|
||||||
KtConstantExpressionElementType BOOLEAN_CONSTANT = new KtConstantExpressionElementType("BOOLEAN_CONSTANT");
|
KtConstantExpressionElementType BOOLEAN_CONSTANT = new KtConstantExpressionElementType("BOOLEAN_CONSTANT");
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any?)
|
||||||
|
|
||||||
|
context(A<String>, B) fun f() {
|
||||||
|
this@A.a.length
|
||||||
|
this@B.b
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
with(A("")) {
|
||||||
|
with(B(null)) {
|
||||||
|
f()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "OK"
|
||||||
|
}
|
||||||
|
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
interface Context {
|
||||||
|
fun h() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open fun f() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
override fun f() {}
|
||||||
|
|
||||||
|
context(Context)
|
||||||
|
inner class C {
|
||||||
|
fun g() {
|
||||||
|
super@B.f()
|
||||||
|
super@Context.<!UNRESOLVED_REFERENCE!>h<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
interface Context {
|
||||||
|
fun h() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
open class A {
|
||||||
|
open fun f() {}
|
||||||
|
}
|
||||||
|
|
||||||
|
class B : A() {
|
||||||
|
override fun f() {}
|
||||||
|
|
||||||
|
context(Context)
|
||||||
|
inner class C {
|
||||||
|
fun g() {
|
||||||
|
super@B.f()
|
||||||
|
<!DEBUG_INFO_MISSING_UNRESOLVED!>super<!><!UNRESOLVED_REFERENCE!>@Context<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>h<!>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+32
@@ -0,0 +1,32 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public open class A {
|
||||||
|
public constructor A()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun f(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class B : A {
|
||||||
|
public constructor B()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ fun f(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
|
public final inner class C {
|
||||||
|
public constructor C()
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun g(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Context {
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open fun h(): kotlin.Unit
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
class A(val a: String?)
|
||||||
|
|
||||||
|
context(A) fun f() {
|
||||||
|
if (<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!> == null) return
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
class A(val a: String?)
|
||||||
|
|
||||||
|
context(A) fun f() {
|
||||||
|
if (this@A.a == null) return
|
||||||
|
<!DEBUG_INFO_SMARTCAST!>this@A.a<!>.length
|
||||||
|
}
|
||||||
+11
@@ -0,0 +1,11 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A(/*0*/ a: kotlin.String?)
|
||||||
|
public final val a: kotlin.String?
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any)
|
||||||
|
class C(val c: Any)
|
||||||
|
|
||||||
|
context(labelAInt@A<Int>, A<String>, labelB@B) fun f() {
|
||||||
|
<!UNRESOLVED_LABEL!>this@labelAInt<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>toFloat<!>()
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@labelB<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
context(labelAInt@A<Int>, A<String>, labelB@B) val C.p: Int
|
||||||
|
get() {
|
||||||
|
<!UNRESOLVED_LABEL!>this@labelAInt<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>toFloat<!>()
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@labelB<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@C<!>.<!UNRESOLVED_REFERENCE!>c<!>
|
||||||
|
this@p.c
|
||||||
|
this.c
|
||||||
|
return 1
|
||||||
|
}
|
||||||
+22
@@ -0,0 +1,22 @@
|
|||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any)
|
||||||
|
class C(val c: Any)
|
||||||
|
|
||||||
|
context(labelAInt@A<Int>, A<String>, labelB@B) fun f() {
|
||||||
|
this@labelAInt.a.toFloat()
|
||||||
|
this@A.a.length
|
||||||
|
this@labelB.b
|
||||||
|
this<!UNRESOLVED_REFERENCE!>@B<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
context(labelAInt@A<Int>, A<String>, labelB@B) val C.p: Int
|
||||||
|
get() {
|
||||||
|
this@labelAInt.a.toFloat()
|
||||||
|
this@A.a.length
|
||||||
|
this<!UNRESOLVED_REFERENCE!>@B<!>
|
||||||
|
this@labelB.b
|
||||||
|
this@C.c
|
||||||
|
this@p.c
|
||||||
|
this.c
|
||||||
|
return 1
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public val C.p: kotlin.Int
|
||||||
|
public fun f(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ T>(/*0*/ a: T)
|
||||||
|
public final val a: T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class B {
|
||||||
|
public constructor B(/*0*/ b: kotlin.Any)
|
||||||
|
public final val b: kotlin.Any
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class C {
|
||||||
|
public constructor C(/*0*/ c: kotlin.Any)
|
||||||
|
public final val c: kotlin.Any
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsClasses.fir.kt
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class A {
|
||||||
|
val x = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
context(A) class B {
|
||||||
|
val prop = <!UNRESOLVED_REFERENCE!>x<!> + <!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>x<!>
|
||||||
|
|
||||||
|
fun f() = <!UNRESOLVED_REFERENCE!>x<!> + <!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>x<!>
|
||||||
|
}
|
||||||
Vendored
+9
@@ -0,0 +1,9 @@
|
|||||||
|
class A {
|
||||||
|
val x = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
context(A) class B {
|
||||||
|
val prop = x + this<!UNRESOLVED_REFERENCE!>@A<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>x<!>
|
||||||
|
|
||||||
|
fun f() = x + this<!UNRESOLVED_REFERENCE!>@A<!>.<!DEBUG_INFO_MISSING_UNRESOLVED!>x<!>
|
||||||
|
}
|
||||||
Vendored
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public final class A {
|
||||||
|
public constructor A()
|
||||||
|
public final val x: kotlin.Int = 1
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class B {
|
||||||
|
public constructor B()
|
||||||
|
public final val prop: [ERROR : Type for x + this@A.x]
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public final fun f(): [ERROR : Error function type]
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any)
|
||||||
|
class C(val c: Any)
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) fun f() {
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!NO_THIS!>this<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) fun C.f() {
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@C<!>.<!UNRESOLVED_REFERENCE!>c<!>
|
||||||
|
this@f.c
|
||||||
|
this.c
|
||||||
|
}
|
||||||
Vendored
+17
@@ -0,0 +1,17 @@
|
|||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any)
|
||||||
|
class C(val c: Any)
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) fun f() {
|
||||||
|
this@A.a.length
|
||||||
|
this@B.b
|
||||||
|
<!NO_THIS!>this<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) fun C.f() {
|
||||||
|
this@A.a.length
|
||||||
|
this@B.b
|
||||||
|
this@C.c
|
||||||
|
this@f.c
|
||||||
|
this.c
|
||||||
|
}
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(): kotlin.Unit
|
||||||
|
public fun C.f(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ T>(/*0*/ a: T)
|
||||||
|
public final val a: T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class B {
|
||||||
|
public constructor B(/*0*/ b: kotlin.Any)
|
||||||
|
public final val b: kotlin.Any
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class C {
|
||||||
|
public constructor C(/*0*/ c: kotlin.Any)
|
||||||
|
public final val c: kotlin.Any
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
+28
@@ -0,0 +1,28 @@
|
|||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any)
|
||||||
|
class C(val c: Any)
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) var p: Int
|
||||||
|
get() {
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>toDouble<!>()
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!NO_THIS!>this<!>
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!NO_THIS!>this<!>
|
||||||
|
field = value
|
||||||
|
}
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) val C.p: Int
|
||||||
|
get() {
|
||||||
|
<!UNRESOLVED_LABEL!>this@A<!>.<!UNRESOLVED_REFERENCE!>a<!>.<!UNRESOLVED_REFERENCE!>length<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@B<!>.<!UNRESOLVED_REFERENCE!>b<!>
|
||||||
|
<!UNRESOLVED_LABEL!>this@C<!>.<!UNRESOLVED_REFERENCE!>c<!>
|
||||||
|
this@p.c
|
||||||
|
this.c
|
||||||
|
return 1
|
||||||
|
}
|
||||||
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
class A<T>(val a: T)
|
||||||
|
class B(val b: Any)
|
||||||
|
class C(val c: Any)
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) var p: Int
|
||||||
|
get() {
|
||||||
|
this@A.a.<!UNRESOLVED_REFERENCE!>toDouble<!>()
|
||||||
|
this@A.a.length
|
||||||
|
this@B.b
|
||||||
|
<!NO_THIS!>this<!>
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
set(value) {
|
||||||
|
this@A.a.length
|
||||||
|
this@B.b
|
||||||
|
<!NO_THIS!>this<!>
|
||||||
|
<!UNRESOLVED_REFERENCE!>field<!> = value
|
||||||
|
}
|
||||||
|
|
||||||
|
context(A<Int>, A<String>, B) val C.p: Int
|
||||||
|
get() {
|
||||||
|
this@A.a.length
|
||||||
|
this@B.b
|
||||||
|
this@C.c
|
||||||
|
this@p.c
|
||||||
|
this.c
|
||||||
|
return 1
|
||||||
|
}
|
||||||
compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.txt
Vendored
+28
@@ -0,0 +1,28 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public var p: kotlin.Int
|
||||||
|
public val C.p: kotlin.Int
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ T>(/*0*/ a: T)
|
||||||
|
public final val a: T
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class B {
|
||||||
|
public constructor B(/*0*/ b: kotlin.Any)
|
||||||
|
public final val b: kotlin.Any
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class C {
|
||||||
|
public constructor C(/*0*/ c: kotlin.Any)
|
||||||
|
public final val c: kotlin.Any
|
||||||
|
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
}
|
||||||
Generated
+36
@@ -10630,6 +10630,42 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/plusMatrix.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/plusMatrix.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("superWithContext.kt")
|
||||||
|
public void testSuperWithContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/superWithContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisIdentifierInfo.kt")
|
||||||
|
public void testThisIdentifierInfo() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisIdentifierInfo.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithCustomLabel.kt")
|
||||||
|
public void testThisWithCustomLabel() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithCustomLabel.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithReceiverLabelsClasses.kt")
|
||||||
|
public void testThisWithReceiverLabelsClasses() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsClasses.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithReceiverLabelsFunctions.kt")
|
||||||
|
public void testThisWithReceiverLabelsFunctions() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsFunctions.kt");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("thisWithReceiverLabelsProperties.kt")
|
||||||
|
public void testThisWithReceiverLabelsProperties() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/thisWithReceiverLabelsProperties.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("typeParameterized.kt")
|
@TestMetadata("typeParameterized.kt")
|
||||||
public void testTypeParameterized() throws Exception {
|
public void testTypeParameterized() throws Exception {
|
||||||
|
|||||||
+6
@@ -16168,6 +16168,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
public void testSimpleCall() throws Exception {
|
public void testSimpleCall() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/simpleCall.kt");
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/simpleCall.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("this.kt")
|
||||||
|
public void testThis() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionFunctions/contextReceivers/this.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -188,9 +188,19 @@ public class DescriptorFactory {
|
|||||||
@NotNull CallableDescriptor owner,
|
@NotNull CallableDescriptor owner,
|
||||||
@Nullable KotlinType receiverParameterType,
|
@Nullable KotlinType receiverParameterType,
|
||||||
@NotNull Annotations annotations
|
@NotNull Annotations annotations
|
||||||
|
) {
|
||||||
|
return createExtensionReceiverParameterForCallable(owner, receiverParameterType, annotations, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
public static ReceiverParameterDescriptor createExtensionReceiverParameterForCallable(
|
||||||
|
@NotNull CallableDescriptor owner,
|
||||||
|
@Nullable KotlinType receiverParameterType,
|
||||||
|
@NotNull Annotations annotations,
|
||||||
|
boolean isContextReceiver
|
||||||
) {
|
) {
|
||||||
return receiverParameterType == null
|
return receiverParameterType == null
|
||||||
? null
|
? null
|
||||||
: new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType, null), annotations);
|
: new ReceiverParameterDescriptorImpl(owner, new ExtensionReceiver(owner, receiverParameterType, null, isContextReceiver), annotations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+15
@@ -35,14 +35,25 @@ import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker;
|
|||||||
public class ExtensionReceiver extends AbstractReceiverValue implements ImplicitReceiver {
|
public class ExtensionReceiver extends AbstractReceiverValue implements ImplicitReceiver {
|
||||||
|
|
||||||
private final CallableDescriptor descriptor;
|
private final CallableDescriptor descriptor;
|
||||||
|
private final boolean isContextReceiver;
|
||||||
|
|
||||||
public ExtensionReceiver(
|
public ExtensionReceiver(
|
||||||
@NotNull CallableDescriptor callableDescriptor,
|
@NotNull CallableDescriptor callableDescriptor,
|
||||||
@NotNull KotlinType receiverType,
|
@NotNull KotlinType receiverType,
|
||||||
@Nullable ReceiverValue original
|
@Nullable ReceiverValue original
|
||||||
|
) {
|
||||||
|
this(callableDescriptor, receiverType, original, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ExtensionReceiver(
|
||||||
|
@NotNull CallableDescriptor callableDescriptor,
|
||||||
|
@NotNull KotlinType receiverType,
|
||||||
|
@Nullable ReceiverValue original,
|
||||||
|
boolean isContextReceiver
|
||||||
) {
|
) {
|
||||||
super(receiverType, original);
|
super(receiverType, original);
|
||||||
this.descriptor = callableDescriptor;
|
this.descriptor = callableDescriptor;
|
||||||
|
this.isContextReceiver = isContextReceiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -61,4 +72,8 @@ public class ExtensionReceiver extends AbstractReceiverValue implements Implicit
|
|||||||
public String toString() {
|
public String toString() {
|
||||||
return getType() + ": Ext {" + descriptor + "}";
|
return getType() + ": Ext {" + descriptor + "}";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isContextReceiver() {
|
||||||
|
return isContextReceiver;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user