diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java index a5fb0b49c0d..368b89893e0 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosticCompilerTestFE10TestdataTestGenerated.java @@ -12687,6 +12687,12 @@ public class DiagnosticCompilerTestFE10TestdataTestGenerated extends AbstractDia 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 @TestMetadata("lazy.kt") public void testLazy() throws Exception { diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java index 3003659ebde..16d3beff44d 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated.java @@ -12687,6 +12687,12 @@ public class LLFirPreresolvedReversedDiagnosticCompilerFE10TestDataTestGenerated 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 @TestMetadata("lazy.kt") public void testLazy() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java index 2b8da0e5a96..2ab269f744e 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirLightTreeOldFrontendDiagnosticsTestGenerated.java @@ -12687,6 +12687,12 @@ public class FirLightTreeOldFrontendDiagnosticsTestGenerated extends AbstractFir 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 @TestMetadata("lazy.kt") public void testLazy() throws Exception { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java index 2ff6bf18491..b51fc06e8fa 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirPsiOldFrontendDiagnosticsTestGenerated.java @@ -12693,6 +12693,12 @@ public class FirPsiOldFrontendDiagnosticsTestGenerated extends AbstractFirPsiDia 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 @TestMetadata("lazy.kt") public void testLazy() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java index f2e2f6c0c95..0e7d16f0332 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenTestGenerated.java @@ -17883,6 +17883,12 @@ public class FirLightTreeBlackBoxCodegenTestGenerated extends AbstractFirLightTr 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 @TestMetadata("multiple.kt") public void testMultiple() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java index bd46db5564e..c3b5485110f 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated.java @@ -17883,6 +17883,12 @@ public class FirLightTreeBlackBoxCodegenWithIrFakeOverrideGeneratorTestGenerated 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 @TestMetadata("multiple.kt") public void testMultiple() throws Exception { diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java index 91bb1b5f2e4..f1686aa3213 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirPsiBlackBoxCodegenTestGenerated.java @@ -17883,6 +17883,12 @@ public class FirPsiBlackBoxCodegenTestGenerated extends AbstractFirPsiBlackBoxCo 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 @TestMetadata("multiple.kt") public void testMultiple() throws Exception { diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt index 1114ce2b85f..9703a4abfb4 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/tower/FirInvokeResolveTowerExtension.kt @@ -443,6 +443,22 @@ private class InvokeFunctionResolveTask( 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( diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt index 20f24b76225..4fd423a64e5 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/transformers/body/resolve/BodyResolveContext.kt @@ -542,7 +542,12 @@ class BodyResolveContext( val forMembersResolution = statics .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( regular = forMembersResolution, diff --git a/compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt b/compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt new file mode 100644 index 00000000000..d1e07a60275 --- /dev/null +++ b/compiler/testData/codegen/box/extensionClasses/lambdaReceiverFromContext.kt @@ -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" +} diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.fir.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.fir.kt new file mode 100644 index 00000000000..cd5ccf402fa --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.fir.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +ContextReceivers + +class Ctx + +fun Ctx.foo() {} + +context(Ctx) +class A { + fun bar(body: Ctx.() -> Unit) { + foo() + body() + } +} diff --git a/compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt b/compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt new file mode 100644 index 00000000000..399292654cb --- /dev/null +++ b/compiler/testData/diagnostics/tests/extensions/contextReceivers/lambdaReceiverFromContext.kt @@ -0,0 +1,13 @@ +// !LANGUAGE: +ContextReceivers + +class Ctx + +fun Ctx.foo() {} + +context(Ctx) +class A { + fun bar(body: Ctx.() -> Unit) { + foo() + body() + } +} diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java index e36e4028526..c06f9f34c72 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/DiagnosticTestGenerated.java @@ -12693,6 +12693,12 @@ public class DiagnosticTestGenerated extends AbstractDiagnosticTest { 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 @TestMetadata("lazy.kt") public void testLazy() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 2d6d3d42427..51e7d99357c 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -17883,6 +17883,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes 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 @TestMetadata("multiple.kt") public void testMultiple() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java index d7d38c26015..de20884f227 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenWithIrInlinerTestGenerated.java @@ -17883,6 +17883,12 @@ public class IrBlackBoxCodegenWithIrInlinerTestGenerated extends AbstractIrBlack 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 @TestMetadata("multiple.kt") public void testMultiple() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index ca91b14cff0..0ff20c2f57b 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -14829,6 +14829,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes 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") public void testMultiple() throws Exception { runTest("compiler/testData/codegen/box/extensionClasses/multiple.kt"); diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt index ac3db61855b..e4a4483bf28 100644 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ScriptingHostTest.kt @@ -292,6 +292,43 @@ class ScriptingHostTest : TestCase() { 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( + compilation = { + updateClasspath(classpathFromClass()) + 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 fun testProvidedPropertiesNullability() { val stringType = KotlinType(String::class)