[FE] Support functional literals with context receivers

This commit is contained in:
Anastasiya Shadrina
2021-08-14 00:07:06 +07:00
committed by TeamCityServer
parent e3f987459c
commit 16b976f0e0
4 changed files with 50 additions and 15 deletions
@@ -198,9 +198,11 @@ class FunctionDescriptorResolver(
} }
val contextReceivers = function.contextReceivers val contextReceivers = function.contextReceivers
val contextReceiverTypes = contextReceivers.mapNotNull { it.typeReference() }.map { val contextReceiverTypes =
typeResolver.resolveType(headerScope, it, trace, true) if (function is KtFunctionLiteral) expectedFunctionType.getContextReceiversTypes()
} else contextReceivers
.mapNotNull { it.typeReference() }
.map { typeResolver.resolveType(headerScope, it, trace, true) }
val valueParameterDescriptors = val valueParameterDescriptors =
createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession) createValueParameterDescriptors(function, functionDescriptor, headerScope, trace, expectedFunctionType, inferenceSession)
@@ -351,6 +353,9 @@ class FunctionDescriptorResolver(
private fun KotlinType.getReceiverType(): KotlinType? = private fun KotlinType.getReceiverType(): KotlinType? =
if (functionTypeExpected()) this.getReceiverTypeFromFunctionType() else null if (functionTypeExpected()) this.getReceiverTypeFromFunctionType() else null
private fun KotlinType.getContextReceiversTypes(): List<KotlinType> =
if (functionTypeExpected()) this.getContextReceiverTypesFromFunctionType() else emptyList()
private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? = private fun KotlinType.getValueParameters(owner: FunctionDescriptor): List<ValueParameterDescriptor>? =
if (functionTypeExpected()) { if (functionTypeExpected()) {
createValueParametersForInvokeInFunctionType(owner, this.getValueParameterTypesFromFunctionType()) createValueParametersForInvokeInFunctionType(owner, this.getValueParameterTypesFromFunctionType())
@@ -1,6 +1,10 @@
class Param class Param
class C class C {
class R val c = 42
}
class R {
val r = 42
}
context(C) context(C)
fun R.f1(g: context(C) R.(Param) -> Unit) { fun R.f1(g: context(C) R.(Param) -> Unit) {
@@ -23,10 +27,20 @@ fun f4(g: context(C) () -> Unit) {
} }
fun test() { fun test() {
val lf1: context(C) R.(Param) -> Unit = { _ -> } val lf1: context(C) R.(Param) -> Unit = { _ ->
val lf2: context(C) (Param) -> Unit = { _ -> } r
val lf3: context(C) R.() -> Unit = { } c
val lf4: context(C) () -> Unit = { } }
val lf2: context(C) (Param) -> Unit = { _ ->
c
}
val lf3: context(C) R.() -> Unit = {
r
c
}
val lf4: context(C) () -> Unit = {
c
}
with(C()) { with(C()) {
with(R()) { with(R()) {
@@ -1,6 +1,10 @@
class Param class Param
class C class C {
class R val c = 42
}
class R {
val r = 42
}
context(C) context(C)
fun R.f1(g: context(C) R.(Param) -> Unit) { fun R.f1(g: context(C) R.(Param) -> Unit) {
@@ -23,10 +27,20 @@ fun f4(g: context(C) () -> Unit) {
} }
fun test() { fun test() {
val lf1: context(C) R.(Param) -> Unit = { _ -> } val lf1: context(C) R.(Param) -> Unit = { _ ->
val lf2: context(C) (Param) -> Unit = { _ -> } r
val lf3: context(C) R.() -> Unit = { } c
val lf4: context(C) () -> Unit = { } }
val lf2: context(C) (Param) -> Unit = { _ ->
c
}
val lf3: context(C) R.() -> Unit = {
r
c
}
val lf4: context(C) () -> Unit = {
c
}
with(C()) { with(C()) {
with(R()) { with(R()) {
@@ -8,6 +8,7 @@ public fun R.f3(/*0*/ g: @kotlin.ContextFunctionTypeParams(count = 1) (R.() -> k
public final class C { public final class C {
public constructor C() public constructor C()
public final val c: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean 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 hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
@@ -22,6 +23,7 @@ public final class Param {
public final class R { public final class R {
public constructor R() public constructor R()
public final val r: kotlin.Int = 42
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean 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 hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String