Implement missing invoke resolution branch with context receivers
#KT-61937 fixed Note: the current implementation only resolves for a single receiver in each group. See KT-62712 and KT-62709 for the followup.
This commit is contained in:
committed by
Space Team
parent
b89d8a65a1
commit
268d058bbb
+6
@@ -12687,6 +12687,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lazy.kt")
|
@TestMetadata("lazy.kt")
|
||||||
public void testLazy() throws Exception {
|
public void testLazy() throws Exception {
|
||||||
|
|||||||
+6
@@ -12687,6 +12687,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lazy.kt")
|
@TestMetadata("lazy.kt")
|
||||||
public void testLazy() throws Exception {
|
public void testLazy() throws Exception {
|
||||||
|
|||||||
+6
@@ -12687,6 +12687,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lazy.kt")
|
@TestMetadata("lazy.kt")
|
||||||
public void testLazy() throws Exception {
|
public void testLazy() throws Exception {
|
||||||
|
|||||||
+6
@@ -12693,6 +12693,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lazy.kt")
|
@TestMetadata("lazy.kt")
|
||||||
public void testLazy() throws Exception {
|
public void testLazy() throws Exception {
|
||||||
|
|||||||
+6
@@ -17883,6 +17883,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr
|
|||||||
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multiple.kt")
|
@TestMetadata("multiple.kt")
|
||||||
public void testMultiple() throws Exception {
|
public void testMultiple() throws Exception {
|
||||||
|
|||||||
+6
@@ -17883,6 +17883,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated
|
|||||||
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multiple.kt")
|
@TestMetadata("multiple.kt")
|
||||||
public void testMultiple() throws Exception {
|
public void testMultiple() throws Exception {
|
||||||
|
|||||||
+6
@@ -17883,6 +17883,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo
|
|||||||
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multiple.kt")
|
@TestMetadata("multiple.kt")
|
||||||
public void testMultiple() throws Exception {
|
public void testMultiple() throws Exception {
|
||||||
|
|||||||
+16
@@ -443,6 +443,22 @@ private class InvokeFunctionResolveTask(
|
|||||||
ExplicitReceiverKind.DISPATCH_RECEIVER
|
ExplicitReceiverKind.DISPATCH_RECEIVER
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
for ((depth, contextReceiverGroup) in towerDataElementsForName.contextReceiverGroups) {
|
||||||
|
val towerGroup =
|
||||||
|
TowerGroup
|
||||||
|
.ContextReceiverGroup(depth)
|
||||||
|
.InvokeExtensionWithImplicitReceiver
|
||||||
|
.withGivenInvokeReceiverGroup(InvokeResolvePriority.INVOKE_EXTENSION)
|
||||||
|
val towerLevel = invokeReceiverValue.toMemberScopeTowerLevel()
|
||||||
|
// TODO: resolve for all receivers in the group, but implement the ambiguity diagnostics first. See KT-62712 and KT-69709
|
||||||
|
contextReceiverGroup.singleOrNull()?.let { contextReceiverValue ->
|
||||||
|
processLevel(
|
||||||
|
towerLevel,
|
||||||
|
info.withReceiverAsArgument(contextReceiverValue.receiverExpression), towerGroup,
|
||||||
|
ExplicitReceiverKind.EXTENSION_RECEIVER
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun processLevelForRegularInvoke(
|
private suspend fun processLevelForRegularInvoke(
|
||||||
|
|||||||
+6
-1
@@ -542,7 +542,12 @@ class BodyResolveContext(
|
|||||||
val forMembersResolution =
|
val forMembersResolution =
|
||||||
statics
|
statics
|
||||||
.addLocalScope(parameterScope)
|
.addLocalScope(parameterScope)
|
||||||
.addContextReceiverGroup(towerElementsForScript.implicitReceivers)
|
// TODO: temporary solution for avoiding problem described in KT-62712, flatten back after fix
|
||||||
|
.let { baseCtx ->
|
||||||
|
towerElementsForScript.implicitReceivers.fold(baseCtx) { ctx, it ->
|
||||||
|
ctx.addContextReceiverGroup(listOf(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val newContexts = FirRegularTowerDataContexts(
|
val newContexts = FirRegularTowerDataContexts(
|
||||||
regular = forMembersResolution,
|
regular = forMembersResolution,
|
||||||
|
|||||||
@@ -0,0 +1,22 @@
|
|||||||
|
// TARGET_BACKEND: JVM_IR
|
||||||
|
// IGNORE_BACKEND_K1: ANY
|
||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
|
||||||
|
class Ctx(val value: Int)
|
||||||
|
|
||||||
|
fun Ctx.foo() = value + 4
|
||||||
|
|
||||||
|
context(Ctx)
|
||||||
|
class A {
|
||||||
|
fun bar(body: Ctx.() -> Int): Int {
|
||||||
|
return foo() *
|
||||||
|
body()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun box(): String {
|
||||||
|
val res = with(Ctx(3)) {
|
||||||
|
A().bar { this.value * 2 }
|
||||||
|
}
|
||||||
|
return if (res == 42) "OK" else "NOK: $res"
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
|
||||||
|
class Ctx
|
||||||
|
|
||||||
|
fun Ctx.foo() {}
|
||||||
|
|
||||||
|
context(Ctx)
|
||||||
|
class A {
|
||||||
|
fun bar(body: Ctx.() -> Unit) {
|
||||||
|
foo()
|
||||||
|
body()
|
||||||
|
}
|
||||||
|
}
|
||||||
Vendored
+13
@@ -0,0 +1,13 @@
|
|||||||
|
// !LANGUAGE: +ContextReceivers
|
||||||
|
|
||||||
|
class Ctx
|
||||||
|
|
||||||
|
fun Ctx.foo() {}
|
||||||
|
|
||||||
|
context(Ctx)
|
||||||
|
class A {
|
||||||
|
fun bar(body: Ctx.() -> Unit) {
|
||||||
|
foo()
|
||||||
|
body<!NO_VALUE_FOR_PARAMETER!>()<!>
|
||||||
|
}
|
||||||
|
}
|
||||||
Generated
+6
@@ -12693,6 +12693,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest {
|
|||||||
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/labelsFromClassNameForbidden.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("lazy.kt")
|
@TestMetadata("lazy.kt")
|
||||||
public void testLazy() throws Exception {
|
public void testLazy() throws Exception {
|
||||||
|
|||||||
+6
@@ -17883,6 +17883,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
|||||||
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multiple.kt")
|
@TestMetadata("multiple.kt")
|
||||||
public void testMultiple() throws Exception {
|
public void testMultiple() throws Exception {
|
||||||
|
|||||||
+6
@@ -17883,6 +17883,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack
|
|||||||
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@TestMetadata("multiple.kt")
|
@TestMetadata("multiple.kt")
|
||||||
public void testMultiple() throws Exception {
|
public void testMultiple() throws Exception {
|
||||||
|
|||||||
+5
@@ -14829,6 +14829,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
|||||||
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/generics.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("lambdaReceiverFromContext.kt")
|
||||||
|
public void testLambdaReceiverFromContext() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("multiple.kt")
|
@TestMetadata("multiple.kt")
|
||||||
public void testMultiple() throws Exception {
|
public void testMultiple() throws Exception {
|
||||||
runTest("compiler/testData/codegen/box/extensionClasses/multiple.kt");
|
runTest("compiler/testData/codegen/box/extensionClasses/multiple.kt");
|
||||||
|
|||||||
+37
@@ -292,6 +292,43 @@ class ScriptingHostTest : TestCase() {
|
|||||||
Assert.assertEquals(result, output)
|
Assert.assertEquals(result, output)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun testScriptImplicitReceiversTransitiveVisibility() {
|
||||||
|
val result = listOf("42")
|
||||||
|
val script = """
|
||||||
|
import kotlin.script.experimental.jvmhost.test.forScript.p1.TestClass
|
||||||
|
|
||||||
|
fun TestClass.foo() = 6
|
||||||
|
|
||||||
|
fun test(body: TestClass.() -> Int): Int {
|
||||||
|
return foo() *
|
||||||
|
body()
|
||||||
|
}
|
||||||
|
|
||||||
|
println(test { 7 })
|
||||||
|
""".trimIndent()
|
||||||
|
val definition = createJvmScriptDefinitionFromTemplate<SimpleScriptTemplate>(
|
||||||
|
compilation = {
|
||||||
|
updateClasspath(classpathFromClass<kotlin.script.experimental.jvmhost.test.forScript.p1.TestClass>())
|
||||||
|
implicitReceivers(
|
||||||
|
kotlin.script.experimental.jvmhost.test.forScript.p1.TestClass::class,
|
||||||
|
)
|
||||||
|
},
|
||||||
|
evaluation = {
|
||||||
|
implicitReceivers(
|
||||||
|
kotlin.script.experimental.jvmhost.test.forScript.p1.TestClass(""),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
val output = captureOut {
|
||||||
|
val evalRes = BasicJvmScriptingHost().eval(
|
||||||
|
script.toScriptSource(), definition.compilationConfiguration, definition.evaluationConfiguration
|
||||||
|
)
|
||||||
|
val retVal = evalRes.valueOrThrow().returnValue
|
||||||
|
if (retVal is ResultValue.Error) throw retVal.error
|
||||||
|
}.lines()
|
||||||
|
Assert.assertEquals(result, output)
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testProvidedPropertiesNullability() {
|
fun testProvidedPropertiesNullability() {
|
||||||
val stringType = KotlinType(String::class)
|
val stringType = KotlinType(String::class)
|
||||||
|
|||||||
Reference in New Issue
Block a user