[FE] Implement temporary resolution algorithm

This commit is contained in:
Anastasiya Shadrina
2021-02-15 18:54:11 +07:00
committed by TeamCityServer
parent d923c95671
commit c34fe8d547
43 changed files with 800 additions and 24 deletions
@@ -10471,12 +10471,6 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
runTest("compiler/testData/diagnostics/tests/extensions/classObject.kt");
}
@Test
@TestMetadata("contextReceiver.kt")
public void testContextReceiver() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceiver.kt");
}
@Test
@TestMetadata("ExtensionFunctions.kt")
public void testExtensionFunctions() throws Exception {
@@ -10572,6 +10566,76 @@ public class FirOldFrontendDiagnosticsTestGenerated extends AbstractFirDiagnosti
public void testVariableInvoke() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/variableInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/extensions/contextReceivers")
@TestDataPath("$PROJECT_ROOT")
public class ContextReceivers {
@Test
public void testAllFilesPresentInContextReceivers() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/extensions/contextReceivers"), Pattern.compile("^(.+)\\.kt$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("dp.kt")
public void testDp() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
}
@Test
@TestMetadata("insideDeclaration.kt")
public void testInsideDeclaration() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/insideDeclaration.kt");
}
@Test
@TestMetadata("lazy.kt")
public void testLazy() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lazy.kt");
}
@Test
@TestMetadata("manyReceivers.kt")
public void testManyReceivers() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/manyReceivers.kt");
}
@Test
@TestMetadata("noExplicitReceiver.kt")
public void testNoExplicitReceiver() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noExplicitReceiver.kt");
}
@Test
@TestMetadata("plusMatrix.kt")
public void testPlusMatrix() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/plusMatrix.kt");
}
@Test
@TestMetadata("typeParameterized.kt")
public void testTypeParameterized() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterized.kt");
}
@Test
@TestMetadata("typeParameterizedList.kt")
public void testTypeParameterizedList() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterizedList.kt");
}
@Test
@TestMetadata("withExplicitReceiver.kt")
public void testWithExplicitReceiver() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiver.kt");
}
@Test
@TestMetadata("withExplicitReceiverError.kt")
public void testWithExplicitReceiverError() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
}
}
}
@Nested
@@ -1194,6 +1194,9 @@ public interface Errors {
DiagnosticFactory1<KtElement, String> ERROR_IN_CONTRACT_DESCRIPTION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory1<KtElement, String> CONTRACT_NOT_ALLOWED = DiagnosticFactory1.create(ERROR);
// Context receivers
DiagnosticFactory1<KtElement, String> NO_CONTEXT_RECEIVER = DiagnosticFactory1.create(ERROR);
// Error sets
ImmutableSet<? extends DiagnosticFactory<?>> UNRESOLVED_REFERENCE_DIAGNOSTICS = ImmutableSet.of(
UNRESOLVED_REFERENCE, NAMED_PARAMETER_NOT_FOUND, UNRESOLVED_REFERENCE_WRONG_RECEIVER);
@@ -1086,6 +1086,8 @@ public class DefaultErrorMessages {
MAP.put(ERROR_IN_CONTRACT_DESCRIPTION, "Error in contract description: {0}", TO_STRING);
MAP.put(CONTRACT_NOT_ALLOWED, "{0}", TO_STRING);
MAP.put(NO_CONTEXT_RECEIVER, "No required context receiver found: {0}", TO_STRING);
MAP.setImmutable();
for (Field field : Errors.class.getFields()) {
@@ -93,6 +93,15 @@ class DiagnosticReporterByTrackingStrategy(
)
)
}
NoContextReceiver::class.java -> {
val callElement = psiKotlinCall.psiCall.callElement
trace.report(
NO_CONTEXT_RECEIVER.on(
callElement,
(diagnostic as NoContextReceiver).receiverDescriptor.value.toString()
)
)
}
}
}
@@ -74,6 +74,12 @@ public abstract class DelegatingResolvedCall<D extends CallableDescriptor> imple
return resolvedCall.getDispatchReceiver();
}
@NotNull
@Override
public List<ReceiverValue> getContextReceivers() {
return resolvedCall.getContextReceivers();
}
@NotNull
@Override
public ExplicitReceiverKind getExplicitReceiverKind() {
@@ -69,6 +69,10 @@ public interface ResolvedCall<D extends CallableDescriptor> {
@Nullable
ReceiverValue getDispatchReceiver();
/** If the target was a function or property with context receivers, this is the value for its context receiver parameters */
@NotNull
List<ReceiverValue> getContextReceivers();
/** Determines whether receiver argument or this object is substituted for explicit receiver */
@NotNull
ExplicitReceiverKind getExplicitReceiverKind();
@@ -288,6 +288,12 @@ public class ResolvedCallImpl<D extends CallableDescriptor> implements MutableRe
return dispatchReceiver;
}
@NotNull
@Override
public List<ReceiverValue> getContextReceivers() {
return Collections.emptyList();
}
@Override
@NotNull
public ExplicitReceiverKind getExplicitReceiverKind() {
@@ -10,6 +10,8 @@ import org.jetbrains.kotlin.builtins.getReceiverTypeFromFunctionType
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.resolve.calls.components.CheckReceivers.candidateDescriptor
import org.jetbrains.kotlin.resolve.calls.components.CheckReceivers.checkReceiver
import org.jetbrains.kotlin.resolve.calls.components.TypeArgumentsToParametersMapper.TypeArgumentsMapping.NoExplicitArguments
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
@@ -24,13 +26,15 @@ import org.jetbrains.kotlin.resolve.calls.tasks.ExplicitReceiverKind.*
import org.jetbrains.kotlin.resolve.calls.tower.InfixCallNoInfixModifier
import org.jetbrains.kotlin.resolve.calls.tower.InvokeConventionCallNoOperatorModifier
import org.jetbrains.kotlin.resolve.calls.tower.VisibilityError
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValueWithSmartCastInfo
import org.jetbrains.kotlin.resolve.scopes.utils.parentsWithSelf
import org.jetbrains.kotlin.types.*
import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
import org.jetbrains.kotlin.types.model.KotlinTypeMarker
import org.jetbrains.kotlin.types.model.TypeConstructorMarker
import org.jetbrains.kotlin.types.model.typeConstructor
import org.jetbrains.kotlin.types.typeUtil.contains
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable
import org.jetbrains.kotlin.types.typeUtil.makeNullable
import org.jetbrains.kotlin.types.typeUtil.*
import org.jetbrains.kotlin.utils.SmartList
import org.jetbrains.kotlin.utils.addToStdlib.cast
import org.jetbrains.kotlin.utils.addToStdlib.compactIfPossible
@@ -680,22 +684,60 @@ internal object CheckReceivers : ResolutionPart() {
}
override fun ResolutionCandidate.process(workIndex: Int) {
if (workIndex == 0) {
checkReceiver(
when (workIndex) {
0 -> checkReceiver(
resolvedCall.dispatchReceiverArgument,
candidateDescriptor.dispatchReceiverParameter,
shouldCheckImplicitInvoke = true,
)
} else {
checkReceiver(
resolvedCall.extensionReceiverArgument,
candidateDescriptor.extensionReceiverParameter,
shouldCheckImplicitInvoke = false, // reproduce old inference behaviour
)
1 -> {
checkReceiver(
resolvedCall.extensionReceiverArgument,
candidateDescriptor.extensionReceiverParameter,
shouldCheckImplicitInvoke = false, // reproduce old inference behaviour
)
}
else -> {
resolvedCall.contextReceiversArguments = searchForAdditionalReceivers() ?: return
for (i in resolvedCall.contextReceiversArguments.indices) {
checkReceiver(
resolvedCall.contextReceiversArguments[i],
candidateDescriptor.contextReceiverParameters[i],
shouldCheckImplicitInvoke = false
)
}
}
}
}
override fun ResolutionCandidate.workCount() = 2
override fun ResolutionCandidate.workCount() = 3
private fun ResolutionCandidate.searchForAdditionalReceivers(): List<SimpleKotlinCallArgument>? {
val result = mutableListOf<ReceiverValueWithSmartCastInfo>()
val candidateReceivers = scopeTower.lexicalScope.parentsWithSelf
.flatMap { if (it is LexicalScope) scopeTower.getImplicitReceivers(it) else emptyList() }
fun KotlinType.prepared(): KotlinType = if (containsTypeParameter()) replaceArgumentsWithStarProjections() else this
for (receiver in candidateDescriptor.contextReceiverParameters) {
val expectedReceiverType = receiver.type
val expectedReceiverTypeClosestBound =
if (expectedReceiverType.isTypeParameter()) expectedReceiverType.supertypes().first()
else expectedReceiverType
val selectedCandidate = candidateReceivers.firstOrNull { candidateReceiver ->
val candidateReceiverType = candidateReceiver.receiverValue.type
org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker.Default.isSubtypeOf(
candidateReceiverType.prepared(),
expectedReceiverTypeClosestBound.prepared()
)
} ?: run {
this.diagnosticsFromResolutionParts.add(NoContextReceiver(receiver))
return null
}
result.add(selectedCandidate)
}
return result.map { ReceiverExpressionKotlinCallArgument(it) }
}
}
internal object CheckArgumentsInParenthesis : ResolutionPart() {
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.resolve.calls.model
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.resolve.calls.components.candidate.ResolutionCandidate
import org.jetbrains.kotlin.resolve.calls.components.candidate.CallableReferenceResolutionCandidate
@@ -272,6 +273,12 @@ class CompatibilityWarningOnArgument(
}
}
class NoContextReceiver(val receiverDescriptor: ReceiverParameterDescriptor) : KotlinCallDiagnostic(INAPPLICABLE) {
override fun report(reporter: DiagnosticReporter) {
reporter.onCall(this)
}
}
class KotlinConstraintSystemDiagnostic(
val error: ConstraintSystemError
) : KotlinCallDiagnostic(error.applicability) {
@@ -76,6 +76,7 @@ abstract class ResolvedCallAtom : ResolvedAtom() {
abstract val explicitReceiverKind: ExplicitReceiverKind
abstract val dispatchReceiverArgument: SimpleKotlinCallArgument?
abstract val extensionReceiverArgument: SimpleKotlinCallArgument?
abstract var contextReceiversArguments: List<SimpleKotlinCallArgument>
abstract val typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
abstract val argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
abstract val freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
@@ -85,6 +85,7 @@ open class MutableResolvedCallAtom(
open val reflectionCandidateType: UnwrappedType? = null,
open val candidate: CallableReferenceResolutionCandidate? = null
) : ResolvedCallAtom() {
override var contextReceiversArguments: List<SimpleKotlinCallArgument> = listOf()
override lateinit var typeArgumentMappingByOriginal: TypeArgumentsToParametersMapper.TypeArgumentsMapping
override lateinit var argumentMappingByOriginal: Map<ValueParameterDescriptor, ResolvedCallArgument>
override lateinit var freshVariablesSubstitutor: FreshVariableNewTypeSubstitutor
@@ -0,0 +1,20 @@
class View
context(View) val Int.dp get() = 42 * this
fun View.f() {
123.dp
with(123) {
dp
}
}
fun Int.g(v: View) {
with(v) {
dp
}
}
fun h() {
123.dp
}
@@ -0,0 +1,20 @@
class View
context(View) val Int.dp get() = 42 * this
fun View.f() {
123.dp
with(123) {
dp
}
}
fun Int.g(v: View) {
with(v) {
dp
}
}
fun h() {
123.<!NO_CONTEXT_RECEIVER!>dp<!>
}
@@ -0,0 +1,13 @@
package
public val kotlin.Int.dp: kotlin.Int
public fun h(): kotlin.Unit
public fun View.f(): kotlin.Unit
public fun kotlin.Int.g(/*0*/ v: View): kotlin.Unit
public final class View {
public constructor View()
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
}
@@ -0,0 +1,48 @@
interface Lazy<T>
context(Lazy<Int>, Lazy<CharSequence>)
fun test1() {}
context(Lazy<T>)
fun <T> Lazy<Int>.test2() {}
context(Lazy<Lazy<T>>)
fun <T> Lazy<Int>.test3() {}
fun <T> f(lazy1: Lazy<Int>, lazy2: Lazy<CharSequence>, lazyT: Lazy<T>, lazyLazyT: Lazy<Lazy<T>>) {
with(lazy1) {
with(lazy2) {
test1()
test2()
test3()
}
}
with(lazy2) {
with(lazy1) {
test1()
test2()
test3()
}
}
with(lazyT) {
with(lazy1) {
test1()
test2()
test3()
}
}
with(lazyLazyT) {
with(lazy1) {
test1()
test2()
test3()
}
}
with(lazy1) {
with(lazyLazyT) {
test1()
test2()
test3()
}
}
}
@@ -0,0 +1,48 @@
interface Lazy<T>
context(Lazy<Int>, Lazy<CharSequence>)
fun test1() {}
context(Lazy<T>)
fun <T> Lazy<Int>.test2() {}
context(Lazy<Lazy<T>>)
fun <T> Lazy<Int>.test3() {}
fun <T> f(lazy1: Lazy<Int>, lazy2: Lazy<CharSequence>, lazyT: Lazy<T>, lazyLazyT: Lazy<Lazy<T>>) {
with(lazy1) {
with(lazy2) {
test1()
test2()
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>test3<!>()
}
}
with(lazy2) {
with(lazy1) {
test1()
test2()
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>test3<!>()
}
}
with(lazyT) {
with(lazy1) {
<!NO_CONTEXT_RECEIVER!>test1()<!>
test2()
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>test3<!>()
}
}
with(lazyLazyT) {
with(lazy1) {
<!NO_CONTEXT_RECEIVER!>test1()<!>
test2()
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>test3<!>()
}
}
with(lazy1) {
with(lazyLazyT) {
<!NO_CONTEXT_RECEIVER!>test1()<!>
test2()
test3()
}
}
}
@@ -0,0 +1,12 @@
package
public fun </*0*/ T> f(/*0*/ lazy1: Lazy<kotlin.Int>, /*1*/ lazy2: Lazy<kotlin.CharSequence>, /*2*/ lazyT: Lazy<T>, /*3*/ lazyLazyT: Lazy<Lazy<T>>): kotlin.Unit
public fun test1(): kotlin.Unit
public fun </*0*/ T> Lazy<kotlin.Int>.test2(): kotlin.Unit
public fun </*0*/ T> Lazy<kotlin.Int>.test3(): kotlin.Unit
public interface Lazy</*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
}
@@ -0,0 +1,35 @@
class A {
val a = 1
}
class B {
val b = 2
}
class C {
val c = 3
}
context(A, B) fun C.f() {}
fun main(a: A, b: B, c: C) {
with(a) {
with(b) {
with(c) {
f()
}
}
}
with(b) {
with(c) {
with(a) {
f()
}
}
}
with(a) {
with(c) {
f()
}
}
}
@@ -0,0 +1,35 @@
class A {
val a = 1
}
class B {
val b = 2
}
class C {
val c = 3
}
context(A, B) fun C.f() {}
fun main(a: A, b: B, c: C) {
with(a) {
with(b) {
with(c) {
f()
}
}
}
with(b) {
with(c) {
with(a) {
f()
}
}
}
with(a) {
with(c) {
<!NO_CONTEXT_RECEIVER!>f()<!>
}
}
}
@@ -0,0 +1,28 @@
package
public fun main(/*0*/ a: A, /*1*/ b: B, /*2*/ c: C): kotlin.Unit
public fun C.f(): kotlin.Unit
public final class A {
public constructor A()
public final val a: 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 b: kotlin.Int = 2
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()
public final val c: kotlin.Int = 3
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
}
@@ -0,0 +1,18 @@
class A
class B
class C
context(A) fun B.f() {}
context(A) fun B.g() {
f()
}
context(A) fun C.h() {
<!INAPPLICABLE_CANDIDATE!>f<!>()
}
fun A.q(b: B) {
with(b) {
f()
}
<!INAPPLICABLE_CANDIDATE!>f<!>()
}
@@ -0,0 +1,18 @@
class A
class B
class C
context(A) fun B.f() {}
context(A) fun B.g() {
f()
}
context(A) fun C.h() {
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>f<!>()
}
fun A.q(b: B) {
with(b) {
f()
}
<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>f<!>()
}
@@ -0,0 +1,27 @@
package
public fun B.f(): kotlin.Unit
public fun B.g(): kotlin.Unit
public fun C.h(): kotlin.Unit
public fun A.q(/*0*/ b: B): kotlin.Unit
public final class A {
public constructor A()
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 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()
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
}
@@ -0,0 +1,15 @@
// FIR_IDENTICAL
// !DIAGNOSTICS: -UNUSED_PARAMETER
interface NumberOperations {
fun Number.plus(other: Number): Number
}
class Matrix
context(NumberOperations) fun Matrix.plus(other: Matrix): Matrix = TODO()
fun NumberOperations.plusMatrix(m1: Matrix, m2: Matrix) {
m1.plus(m2)
m2.plus(m1)
}
@@ -0,0 +1,18 @@
package
public fun Matrix.plus(/*0*/ other: Matrix): Matrix
public fun NumberOperations.plusMatrix(/*0*/ m1: Matrix, /*1*/ m2: Matrix): kotlin.Unit
public final class Matrix {
public constructor Matrix()
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 interface NumberOperations {
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 abstract fun kotlin.Number.plus(/*0*/ other: kotlin.Number): kotlin.Number
}
@@ -0,0 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A
class B<X>(val x: X)
context(T)
fun <T> T.f(t: B<T>) {}
fun Int.main(a: A, b: B<String>) {
a.<!INAPPLICABLE_CANDIDATE!>f<!>(b)
}
@@ -0,0 +1,11 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
class A
class B<X>(val x: X)
context(T)
fun <T> T.f(t: B<T>) {}
fun Int.main(a: A, b: B<String>) {
a.f(<!TYPE_MISMATCH, TYPE_MISMATCH!>b<!>)
}
@@ -0,0 +1,19 @@
package
public fun </*0*/ T> T.f(/*0*/ t: B<T>): kotlin.Unit
public fun kotlin.Int.main(/*0*/ a: A, /*1*/ b: B<kotlin.String>): kotlin.Unit
public final class A {
public constructor A()
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*/ X> {
public constructor B</*0*/ X>(/*0*/ x: X)
public final val x: X
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
}
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T> listOf(vararg e: T): List<T> = null!!
class A<T>
context(List<T>)
fun <T> A<T>.f() {}
fun main() {
with(listOf(1, 2, 3)) {
A<Int>().f()
}
with(listOf("1", "2", "3")) {
A<Int>().f()
}
}
@@ -0,0 +1,17 @@
// !DIAGNOSTICS: -UNUSED_PARAMETER
fun <T> listOf(vararg e: T): List<T> = null!!
class A<T>
context(List<T>)
fun <T> A<T>.f() {}
fun main() {
with(listOf(1, 2, 3)) {
A<Int>().f()
}
with(listOf("1", "2", "3")) {
A<Int>().<!UNRESOLVED_REFERENCE_WRONG_RECEIVER!>f<!>()
}
}
@@ -0,0 +1,12 @@
package
public fun </*0*/ T> listOf(/*0*/ vararg e: T /*kotlin.Array<out T>*/): kotlin.collections.List<T>
public fun main(): kotlin.Unit
public fun </*0*/ T> A<T>.f(): 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
}
@@ -0,0 +1,18 @@
open class A
class B
class C: A()
context(A)
fun B.f() {}
fun main() {
val b = B()
b.f()
with(A()) {
b.f()
}
with(C()) {
b.f()
}
}
@@ -0,0 +1,18 @@
open class A
class B
class C: A()
context(A)
fun B.f() {}
fun main() {
val b = B()
b.<!NO_CONTEXT_RECEIVER!>f()<!>
with(A()) {
b.f()
}
with(C()) {
b.f()
}
}
@@ -0,0 +1,25 @@
package
public fun main(): kotlin.Unit
public fun B.f(): kotlin.Unit
public open class A {
public constructor A()
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 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 : A {
public constructor C()
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
}
@@ -0,0 +1,18 @@
class A
class B
class C
context(A)
fun B.f() {}
fun main() {
val b = B()
b.f()
with(A()) {
b.f()
}
with(C()) {
b.f()
}
}
@@ -0,0 +1,18 @@
class A
class B
class C
context(A)
fun B.f() {}
fun main() {
val b = B()
b.<!NO_CONTEXT_RECEIVER!>f()<!>
with(A()) {
b.f()
}
with(C()) {
b.<!NO_CONTEXT_RECEIVER!>f()<!>
}
}
@@ -0,0 +1,25 @@
package
public fun main(): kotlin.Unit
public fun B.f(): kotlin.Unit
public final class A {
public constructor A()
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 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()
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
}
@@ -10477,12 +10477,6 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
runTest("compiler/testData/diagnostics/tests/extensions/classObject.kt");
}
@Test
@TestMetadata("contextReceiver.kt")
public void testContextReceiver() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceiver.kt");
}
@Test
@TestMetadata("ExtensionFunctions.kt")
public void testExtensionFunctions() throws Exception {
@@ -10578,6 +10572,76 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
public void testVariableInvoke() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/variableInvoke.kt");
}
@Nested
@TestMetadata("compiler/testData/diagnostics/tests/extensions/contextReceivers")
@TestDataPath("$PROJECT_ROOT")
public class ContextReceivers {
@Test
public void testAllFilesPresentInContextReceivers() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/diagnostics/tests/extensions/contextReceivers"), Pattern.compile("^(.*)\\.kts?$"), Pattern.compile("^(.+)\\.fir\\.kts?$"), true);
}
@Test
@TestMetadata("dp.kt")
public void testDp() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/dp.kt");
}
@Test
@TestMetadata("insideDeclaration.kt")
public void testInsideDeclaration() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/insideDeclaration.kt");
}
@Test
@TestMetadata("lazy.kt")
public void testLazy() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lazy.kt");
}
@Test
@TestMetadata("manyReceivers.kt")
public void testManyReceivers() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/manyReceivers.kt");
}
@Test
@TestMetadata("noExplicitReceiver.kt")
public void testNoExplicitReceiver() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/noExplicitReceiver.kt");
}
@Test
@TestMetadata("plusMatrix.kt")
public void testPlusMatrix() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/plusMatrix.kt");
}
@Test
@TestMetadata("typeParameterized.kt")
public void testTypeParameterized() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterized.kt");
}
@Test
@TestMetadata("typeParameterizedList.kt")
public void testTypeParameterizedList() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/typeParameterizedList.kt");
}
@Test
@TestMetadata("withExplicitReceiver.kt")
public void testWithExplicitReceiver() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiver.kt");
}
@Test
@TestMetadata("withExplicitReceiverError.kt")
public void testWithExplicitReceiverError() throws Exception {
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/withExplicitReceiverError.kt");
}
}
}
@Nested
@@ -84,6 +84,8 @@ fun KotlinType.isPrimitiveNumberOrNullableType(): Boolean =
fun KotlinType.isTypeParameter(): Boolean = TypeUtils.isTypeParameter(this)
fun KotlinType.containsTypeParameter(): Boolean = TypeUtils.contains(this) { t -> TypeUtils.isTypeParameter(t) }
fun KotlinType.upperBoundedByPrimitiveNumberOrNullableType(): Boolean =
TypeUtils.getTypeParameterDescriptorOrNull(this)?.upperBounds?.any {
it.isPrimitiveNumberOrNullableType() || it.upperBoundedByPrimitiveNumberOrNullableType()
@@ -233,6 +233,7 @@ private fun resolveAccessorCall(
override fun getResultingDescriptor() = suspendPropertyDescriptor
override fun getExtensionReceiver() = null
override fun getDispatchReceiver() = null
override fun getContextReceivers(): List<ReceiverValue> = emptyList()
override fun getExplicitReceiverKind() = ExplicitReceiverKind.NO_EXPLICIT_RECEIVER
override fun getValueArguments(): MutableMap<ValueParameterDescriptor, ResolvedValueArgument> = mutableMapOf()
override fun getValueArgumentsByIndex(): MutableList<ResolvedValueArgument> = mutableListOf()