From 49559d2a5a203a8c071d3f121e5a1fb1a9c49e0b Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Wed, 10 Jan 2024 17:14:38 +0100 Subject: [PATCH] K2 Scripting: fix implicit receivers resolution order #KT-65975 fixed --- .../kotlin/fir/declarations/ScriptScopes.kt | 2 +- .../jvmhost/test/ScriptingHostTest.kt | 55 +++++++++++++++++++ .../jvmhost/test/forScript/TestClass.kt | 13 +++++ 3 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/forScript/TestClass.kt diff --git a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ScriptScopes.kt b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ScriptScopes.kt index 74973ccb7da..e5121196a50 100644 --- a/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ScriptScopes.kt +++ b/compiler/fir/semantics/src/org/jetbrains/kotlin/fir/declarations/ScriptScopes.kt @@ -26,7 +26,7 @@ fun SessionHolder.collectTowerDataElementsForScript(owner: FirScript): TowerElem owner.symbol, receiver.typeRef.coneType, receiver.labelName, session, scopeSession, contextReceiverNumber = index, ) - } + }.asReversed() return TowerElementsForScript( contextReceivers, 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 e4a4483bf28..5361865844e 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,61 @@ class ScriptingHostTest : TestCase() { Assert.assertEquals(result, output) } + fun testScriptWithImplicitReceiversWithSameNamedProperty() { + val result = listOf("first") + val script = "println(v)" + val definition = createJvmScriptDefinitionFromTemplate( + compilation = { + updateClasspath(classpathFromClass()) + implicitReceivers( + kotlin.script.experimental.jvmhost.test.forScript.TestClass1::class, + kotlin.script.experimental.jvmhost.test.forScript.TestClass2::class + ) + }, + evaluation = { + implicitReceivers( + kotlin.script.experimental.jvmhost.test.forScript.TestClass1("first"), + kotlin.script.experimental.jvmhost.test.forScript.TestClass2("second") + ) + } + ) + val output = captureOut { + val retVal = BasicJvmScriptingHost().eval( + script.toScriptSource(), definition.compilationConfiguration, definition.evaluationConfiguration + ).valueOrThrow().returnValue + if (retVal is ResultValue.Error) throw retVal.error + }.lines() + Assert.assertEquals(result, output) + } + + fun testScriptWithImplicitReceiverAndBaseClassWithSameNamedProperty() { + val result = listOf("base") + val script = "println(v)" + val definition = createJvmScriptDefinitionFromTemplate( + compilation = { + updateClasspath(classpathFromClass()) + implicitReceivers( + kotlin.script.experimental.jvmhost.test.forScript.TestClass1::class + ) + baseClass( + kotlin.script.experimental.jvmhost.test.forScript.Base::class + ) + }, + evaluation = { + implicitReceivers( + kotlin.script.experimental.jvmhost.test.forScript.TestClass1("receiver") + ) + } + ) + val output = captureOut { + val retVal = BasicJvmScriptingHost().eval( + script.toScriptSource(), definition.compilationConfiguration, definition.evaluationConfiguration + ).valueOrThrow().returnValue + if (retVal is ResultValue.Error) throw retVal.error + }.lines() + Assert.assertEquals(result, output) + } + fun testScriptImplicitReceiversTransitiveVisibility() { val result = listOf("42") val script = """ diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/forScript/TestClass.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/forScript/TestClass.kt new file mode 100644 index 00000000000..1013984a0eb --- /dev/null +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/forScript/TestClass.kt @@ -0,0 +1,13 @@ +/* + * Copyright 2010-2023 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 kotlin.script.experimental.jvmhost.test.forScript + +open class Base { + val v: String = "base" +} + +class TestClass1(val v: String) +class TestClass2(val v: String)