[FE] Support context receivers on classes
This commit is contained in:
committed by
TeamCityServer
parent
c34fe8d547
commit
f4ddf66ac4
+12
@@ -10582,6 +10582,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericOuterClass.kt")
|
||||||
|
public void testGenericOuterClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/genericOuterClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("insideDeclaration.kt")
|
@TestMetadata("insideDeclaration.kt")
|
||||||
public void testInsideDeclaration() throws Exception {
|
public void testInsideDeclaration() throws Exception {
|
||||||
@@ -10606,6 +10612,12 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noExplicitReceiver.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noExplicitReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClass.kt")
|
||||||
|
public void testOuterClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/outerClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("plusMatrix.kt")
|
@TestMetadata("plusMatrix.kt")
|
||||||
public void testPlusMatrix() throws Exception {
|
public void testPlusMatrix() throws Exception {
|
||||||
|
|||||||
+1
@@ -167,6 +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 getPsiOrParent() = _parent.psiOrParent
|
override fun getPsiOrParent() = _parent.psiOrParent
|
||||||
override fun getParent() = _parent.psiOrParent
|
override fun getParent() = _parent.psiOrParent
|
||||||
|
|||||||
+1
-3
@@ -25,8 +25,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.*
|
import org.jetbrains.kotlin.resolve.scopes.*
|
||||||
import org.jetbrains.kotlin.resolve.scopes.utils.ErrorLexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.utils.ErrorLexicalScope
|
||||||
import org.jetbrains.kotlin.storage.StorageManager
|
import org.jetbrains.kotlin.storage.StorageManager
|
||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
class ClassResolutionScopesSupport(
|
class ClassResolutionScopesSupport(
|
||||||
private val classDescriptor: ClassDescriptor,
|
private val classDescriptor: ClassDescriptor,
|
||||||
@@ -69,7 +67,7 @@ class ClassResolutionScopesSupport(
|
|||||||
scopeWithGenerics,
|
scopeWithGenerics,
|
||||||
classDescriptor,
|
classDescriptor,
|
||||||
true,
|
true,
|
||||||
listOf(classDescriptor.thisAsReceiverParameter),
|
classDescriptor.contextReceivers + classDescriptor.thisAsReceiverParameter,
|
||||||
LexicalScopeKind.CLASS_MEMBER_SCOPE
|
LexicalScopeKind.CLASS_MEMBER_SCOPE
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-1
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.descriptors.*;
|
|||||||
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
|
import org.jetbrains.kotlin.descriptors.impl.ClassDescriptorBase;
|
||||||
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
|
import org.jetbrains.kotlin.descriptors.impl.FunctionDescriptorImpl;
|
||||||
|
import org.jetbrains.kotlin.descriptors.impl.ReceiverParameterDescriptorImpl;
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0;
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation;
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||||
@@ -39,6 +40,7 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.ClassMemberDeclarationProv
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
import org.jetbrains.kotlin.resolve.scopes.MemberScope;
|
||||||
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum;
|
import org.jetbrains.kotlin.resolve.scopes.StaticScopeForKotlinEnum;
|
||||||
|
import org.jetbrains.kotlin.resolve.scopes.receivers.ExtensionClassReceiver;
|
||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElementKt;
|
||||||
import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
|
import org.jetbrains.kotlin.storage.MemoizedFunctionToNotNull;
|
||||||
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
import org.jetbrains.kotlin.storage.NotNullLazyValue;
|
||||||
@@ -51,6 +53,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
import static kotlin.collections.CollectionsKt.firstOrNull;
|
import static kotlin.collections.CollectionsKt.firstOrNull;
|
||||||
import static org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PRIVATE;
|
import static org.jetbrains.kotlin.descriptors.DescriptorVisibilities.PRIVATE;
|
||||||
@@ -104,6 +107,8 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
|
|
||||||
private final NotNullLazyValue<Collection<ClassDescriptor>> sealedSubclasses;
|
private final NotNullLazyValue<Collection<ClassDescriptor>> sealedSubclasses;
|
||||||
|
|
||||||
|
private final NotNullLazyValue<List<ReceiverParameterDescriptor>> contextReceivers;
|
||||||
|
|
||||||
public LazyClassDescriptor(
|
public LazyClassDescriptor(
|
||||||
@NotNull LazyClassContext c,
|
@NotNull LazyClassContext c,
|
||||||
@NotNull DeclarationDescriptor containingDeclaration,
|
@NotNull DeclarationDescriptor containingDeclaration,
|
||||||
@@ -294,9 +299,23 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
storageManager.createLazyValue(() -> {
|
storageManager.createLazyValue(() -> {
|
||||||
if (getModality() == Modality.SEALED) {
|
if (getModality() == Modality.SEALED) {
|
||||||
return c.getSealedClassInheritorsProvider().computeSealedSubclasses(this, freedomForSealedInterfacesSupported);
|
return c.getSealedClassInheritorsProvider().computeSealedSubclasses(this, freedomForSealedInterfacesSupported);
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
});
|
||||||
|
this.contextReceivers = storageManager.createLazyValue(() -> {
|
||||||
|
if (classOrObject == null) {
|
||||||
|
return CollectionsKt.emptyList();
|
||||||
|
}
|
||||||
|
return classOrObject.getContextReceiverTypeReferences().stream().map(typeReference -> {
|
||||||
|
KotlinType kotlinType = c.getTypeResolver().resolveType(getScopeForClassHeaderResolution(), typeReference, c.getTrace(), true);
|
||||||
|
return new ReceiverParameterDescriptorImpl(
|
||||||
|
this,
|
||||||
|
new ExtensionClassReceiver(this, kotlinType, null),
|
||||||
|
Annotations.Companion.getEMPTY()
|
||||||
|
);
|
||||||
|
}).collect(Collectors.toList());
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -432,6 +451,12 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getConstructors();
|
return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getConstructors();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<ReceiverParameterDescriptor> getContextReceivers() {
|
||||||
|
return contextReceivers.invoke();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
public ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor() {
|
||||||
return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getPrimaryConstructor();
|
return ((LazyClassMemberScope) getUnsubstitutedMemberScope()).getPrimaryConstructor();
|
||||||
@@ -642,6 +667,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraCompanionObjects());
|
ForceResolveUtil.forceResolveAllContents(getDescriptorsForExtraCompanionObjects());
|
||||||
ForceResolveUtil.forceResolveAllContents(getUnsubstitutedMemberScope());
|
ForceResolveUtil.forceResolveAllContents(getUnsubstitutedMemberScope());
|
||||||
ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
|
ForceResolveUtil.forceResolveAllContents(getTypeConstructor());
|
||||||
|
ForceResolveUtil.forceResolveAllContents(this.getContextReceivers());
|
||||||
}
|
}
|
||||||
|
|
||||||
// Note: headers of member classes' members are not resolved
|
// Note: headers of member classes' members are not resolved
|
||||||
@@ -671,6 +697,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
|
|||||||
}
|
}
|
||||||
getUnsubstitutedPrimaryConstructor();
|
getUnsubstitutedPrimaryConstructor();
|
||||||
getVisibility();
|
getVisibility();
|
||||||
|
getContextReceivers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -608,6 +608,10 @@ open class IrBasedClassDescriptor(owner: IrClass) : ClassDescriptor, IrBasedDecl
|
|||||||
|
|
||||||
override fun getThisAsReceiverParameter() = owner.thisReceiver?.toIrBasedDescriptor() as ReceiverParameterDescriptor
|
override fun getThisAsReceiverParameter() = owner.thisReceiver?.toIrBasedDescriptor() as ReceiverParameterDescriptor
|
||||||
|
|
||||||
|
override fun getContextReceivers(): List<ReceiverParameterDescriptor> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
override fun getUnsubstitutedPrimaryConstructor() =
|
override fun getUnsubstitutedPrimaryConstructor() =
|
||||||
owner.declarations.filterIsInstance<IrConstructor>().singleOrNull { it.isPrimary }?.toIrBasedDescriptor()
|
owner.declarations.filterIsInstance<IrConstructor>().singleOrNull { it.isPrimary }?.toIrBasedDescriptor()
|
||||||
|
|
||||||
@@ -734,6 +738,10 @@ open class IrBasedEnumEntryDescriptor(owner: IrEnumEntry) : ClassDescriptor, IrB
|
|||||||
|
|
||||||
override fun getThisAsReceiverParameter() = (owner.parent as IrClass).toIrBasedDescriptor().thisAsReceiverParameter
|
override fun getThisAsReceiverParameter() = (owner.parent as IrClass).toIrBasedDescriptor().thisAsReceiverParameter
|
||||||
|
|
||||||
|
override fun getContextReceivers(): List<ReceiverParameterDescriptor> {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? {
|
override fun getUnsubstitutedPrimaryConstructor(): ClassConstructorDescriptor? {
|
||||||
TODO("not implemented")
|
TODO("not implemented")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import com.intellij.psi.impl.CheckUtil
|
|||||||
import com.intellij.psi.stubs.IStubElementType
|
import com.intellij.psi.stubs.IStubElementType
|
||||||
import com.intellij.psi.tree.TokenSet
|
import com.intellij.psi.tree.TokenSet
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import org.jetbrains.kotlin.KtNodeTypes
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.name.ClassId
|
import org.jetbrains.kotlin.name.ClassId
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
@@ -186,6 +187,23 @@ abstract class KtClassOrObject :
|
|||||||
parts.reverse()
|
parts.reverse()
|
||||||
return parts.joinToString(separator = ".")
|
return parts.joinToString(separator = ".")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun getContextReceiverTypeReferences(): List<KtTypeReference> {
|
||||||
|
val stub = stub
|
||||||
|
if (stub != null) {
|
||||||
|
return getStubOrPsiChildrenAsList(KtStubElementTypes.TYPE_REFERENCE)
|
||||||
|
}
|
||||||
|
var node = node.firstChildNode
|
||||||
|
while (node != null) {
|
||||||
|
val tt = node.elementType
|
||||||
|
if (tt === KtNodeTypes.CONTEXT_RECEIVER) {
|
||||||
|
val contextReceiver = node.psi as KtContextReceiver
|
||||||
|
return contextReceiver.typeReferences()
|
||||||
|
}
|
||||||
|
node = node.treeNext
|
||||||
|
}
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -58,6 +58,10 @@ public interface KtPureClassOrObject extends KtPureElement, KtDeclarationContain
|
|||||||
@ReadOnly
|
@ReadOnly
|
||||||
List<KtSecondaryConstructor> getSecondaryConstructors();
|
List<KtSecondaryConstructor> getSecondaryConstructors();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@ReadOnly
|
||||||
|
List<KtTypeReference> getContextReceiverTypeReferences();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
KtClassBody getBody();
|
KtClassBody getBody();
|
||||||
}
|
}
|
||||||
|
|||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
context(T) class A<T>
|
||||||
|
|
||||||
|
context(Collection<P>) class B<P>
|
||||||
|
|
||||||
|
fun Int.foo() {
|
||||||
|
A<Int>()
|
||||||
|
A<String>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Collection<Int>.bar() {
|
||||||
|
B<Int>()
|
||||||
|
B<String>()
|
||||||
|
}
|
||||||
+13
@@ -0,0 +1,13 @@
|
|||||||
|
context(T) class A<T>
|
||||||
|
|
||||||
|
context(Collection<P>) class B<P>
|
||||||
|
|
||||||
|
fun Int.foo() {
|
||||||
|
A<Int>()
|
||||||
|
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>A<!><String>()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Collection<Int>.bar() {
|
||||||
|
B<Int>()
|
||||||
|
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>B<!><String>()
|
||||||
|
}
|
||||||
+18
@@ -0,0 +1,18 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun kotlin.collections.Collection<kotlin.Int>.bar(): kotlin.Unit
|
||||||
|
public fun kotlin.Int.foo(): kotlin.Unit
|
||||||
|
|
||||||
|
public final class A</*0*/ T> {
|
||||||
|
public constructor A</*0*/ 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</*0*/ P> {
|
||||||
|
public constructor B</*0*/ P>()
|
||||||
|
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
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
class Outer {
|
||||||
|
val x: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
context(Outer)
|
||||||
|
class Inner(arg: Any) {
|
||||||
|
fun bar() = <!UNRESOLVED_REFERENCE!>x<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f(outer: Outer) {
|
||||||
|
Inner(1)
|
||||||
|
with(outer) {
|
||||||
|
Inner(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+17
@@ -0,0 +1,17 @@
|
|||||||
|
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||||
|
|
||||||
|
class Outer {
|
||||||
|
val x: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
context(Outer)
|
||||||
|
class Inner(arg: Any) {
|
||||||
|
fun bar() = x
|
||||||
|
}
|
||||||
|
|
||||||
|
fun f(outer: Outer) {
|
||||||
|
<!NO_CONTEXT_RECEIVER!>Inner(1)<!>
|
||||||
|
with(outer) {
|
||||||
|
Inner(3)
|
||||||
|
}
|
||||||
|
}
|
||||||
+19
@@ -0,0 +1,19 @@
|
|||||||
|
package
|
||||||
|
|
||||||
|
public fun f(/*0*/ outer: Outer): kotlin.Unit
|
||||||
|
|
||||||
|
public final class Inner {
|
||||||
|
public constructor Inner(/*0*/ arg: kotlin.Any)
|
||||||
|
public final fun bar(): kotlin.Int
|
||||||
|
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 Outer {
|
||||||
|
public constructor Outer()
|
||||||
|
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
|
||||||
|
}
|
||||||
Generated
+12
@@ -10588,6 +10588,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("genericOuterClass.kt")
|
||||||
|
public void testGenericOuterClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/genericOuterClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("insideDeclaration.kt")
|
@TestMetadata("insideDeclaration.kt")
|
||||||
public void testInsideDeclaration() throws Exception {
|
public void testInsideDeclaration() throws Exception {
|
||||||
@@ -10612,6 +10618,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noExplicitReceiver.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noExplicitReceiver.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("outerClass.kt")
|
||||||
|
public void testOuterClass() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/outerClass.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("plusMatrix.kt")
|
@TestMetadata("plusMatrix.kt")
|
||||||
public void testPlusMatrix() throws Exception {
|
public void testPlusMatrix() throws Exception {
|
||||||
|
|||||||
@@ -77,6 +77,10 @@ public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters,
|
|||||||
@NotNull
|
@NotNull
|
||||||
ReceiverParameterDescriptor getThisAsReceiverParameter();
|
ReceiverParameterDescriptor getThisAsReceiverParameter();
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@ReadOnly
|
||||||
|
List<ReceiverParameterDescriptor> getContextReceivers();
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor();
|
ClassConstructorDescriptor getUnsubstitutedPrimaryConstructor();
|
||||||
|
|
||||||
|
|||||||
+7
@@ -32,6 +32,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.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor {
|
public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor {
|
||||||
@@ -114,6 +115,12 @@ public abstract class AbstractClassDescriptor extends ModuleAwareClassDescriptor
|
|||||||
return thisAsReceiverParameter.invoke();
|
return thisAsReceiverParameter.invoke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<ReceiverParameterDescriptor> getContextReceivers() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments, @NotNull KotlinTypeRefiner kotlinTypeRefiner) {
|
public MemberScope getMemberScope(@NotNull List<? extends TypeProjection> typeArguments, @NotNull KotlinTypeRefiner kotlinTypeRefiner) {
|
||||||
|
|||||||
+10
-1
@@ -70,7 +70,7 @@ public class ClassConstructorDescriptorImpl extends FunctionDescriptorImpl imple
|
|||||||
@NotNull List<TypeParameterDescriptor> typeParameterDescriptors
|
@NotNull List<TypeParameterDescriptor> typeParameterDescriptors
|
||||||
) {
|
) {
|
||||||
super.initialize(
|
super.initialize(
|
||||||
null, calculateDispatchReceiverParameter(), Collections.<ReceiverParameterDescriptor>emptyList(),
|
null, calculateDispatchReceiverParameter(), calculateAdditionalReceiverParameters(),
|
||||||
typeParameterDescriptors,
|
typeParameterDescriptors,
|
||||||
unsubstitutedValueParameters, null,
|
unsubstitutedValueParameters, null,
|
||||||
Modality.FINAL, visibility);
|
Modality.FINAL, visibility);
|
||||||
@@ -97,6 +97,15 @@ public class ClassConstructorDescriptorImpl extends FunctionDescriptorImpl imple
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
List<ReceiverParameterDescriptor> calculateAdditionalReceiverParameters() {
|
||||||
|
ClassDescriptor classDescriptor = getContainingDeclaration();
|
||||||
|
if (!classDescriptor.getContextReceivers().isEmpty()) {
|
||||||
|
return classDescriptor.getContextReceivers();
|
||||||
|
}
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public ClassDescriptor getContainingDeclaration() {
|
public ClassDescriptor getContainingDeclaration() {
|
||||||
|
|||||||
+7
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.types.checker.KotlinTypeRefiner;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor {
|
public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor {
|
||||||
@@ -156,6 +157,12 @@ public class LazySubstitutingClassDescriptor extends ModuleAwareClassDescriptor
|
|||||||
throw new UnsupportedOperationException(); // TODO
|
throw new UnsupportedOperationException(); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public List<ReceiverParameterDescriptor> getContextReceivers() {
|
||||||
|
return Collections.emptyList();
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@Override
|
@Override
|
||||||
public Collection<ClassConstructorDescriptor> getConstructors() {
|
public Collection<ClassConstructorDescriptor> getConstructors() {
|
||||||
|
|||||||
+23
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* 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.resolve.scopes.receivers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
class ExtensionClassReceiver(
|
||||||
|
val classDescriptor: ClassDescriptor,
|
||||||
|
receiverType: KotlinType,
|
||||||
|
original: ReceiverValue?
|
||||||
|
): AbstractReceiverValue(receiverType, original), ImplicitReceiver {
|
||||||
|
override val declarationDescriptor: DeclarationDescriptor
|
||||||
|
get() = classDescriptor
|
||||||
|
|
||||||
|
override fun replaceType(newType: KotlinType): ReceiverValue = ExtensionClassReceiver(classDescriptor, newType, original)
|
||||||
|
|
||||||
|
override fun toString(): String = "$type: Ext { $classDescriptor }"
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user