diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt index e43e806bd2f..c5bd2e1581e 100644 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ReplTest.kt @@ -12,11 +12,12 @@ import org.jetbrains.kotlin.descriptors.ScriptDescriptor import org.jetbrains.kotlin.scripting.compiler.plugin.impl.KJvmReplCompilerImpl import org.junit.Assert import org.junit.Test -import kotlin.script.experimental.annotations.KotlinScript import kotlin.script.experimental.api.* import kotlin.script.experimental.host.toScriptSource -import kotlin.script.experimental.jvm.*import kotlin.script.experimental.jvm.util.classpathFromClass -import kotlin.script.experimental.jvmhost.createJvmCompilationConfigurationFromTemplate +import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator +import kotlin.script.experimental.jvm.baseClassLoader +import kotlin.script.experimental.jvm.defaultJvmScriptingHostConfiguration +import kotlin.script.experimental.jvm.jvm class ReplTest : TestCase() { @@ -101,67 +102,67 @@ class ReplTest : TestCase() { sequenceOf(RuntimeException("abc"), null, 4) ) } +} - fun evaluateInRepl( - compilationConfiguration: ScriptCompilationConfiguration, - evaluationConfiguration: ScriptEvaluationConfiguration, - snippets: Sequence - ): Sequence> { - val replCompilerProxy = - KJvmReplCompilerImpl(defaultJvmScriptingHostConfiguration) - val compilationState = replCompilerProxy.createReplCompilationState(compilationConfiguration) - val compilationHistory = BasicReplStageHistory() - val replEvaluator = BasicJvmScriptEvaluator() - var currentEvalConfig = evaluationConfiguration - return snippets.mapIndexed { snippetNo, snippetText -> - val snippetSource = snippetText.toScriptSource("Line_$snippetNo.simplescript.kts") - val snippetId = ReplSnippetIdImpl(snippetNo, 0, snippetSource) - replCompilerProxy.compileReplSnippet(compilationState, snippetSource, snippetId, compilationHistory) - .onSuccess { - runBlocking { - replEvaluator(it, currentEvalConfig) - } +fun evaluateInRepl( + compilationConfiguration: ScriptCompilationConfiguration, + evaluationConfiguration: ScriptEvaluationConfiguration?, + snippets: Sequence +): Sequence> { + val replCompilerProxy = + KJvmReplCompilerImpl(defaultJvmScriptingHostConfiguration) + val compilationState = replCompilerProxy.createReplCompilationState(compilationConfiguration) + val compilationHistory = BasicReplStageHistory() + val replEvaluator = BasicJvmScriptEvaluator() + var currentEvalConfig = evaluationConfiguration ?: ScriptEvaluationConfiguration() + return snippets.mapIndexed { snippetNo, snippetText -> + val snippetSource = snippetText.toScriptSource("Line_$snippetNo.${compilationConfiguration[ScriptCompilationConfiguration.fileExtension]}") + val snippetId = ReplSnippetIdImpl(snippetNo, 0, snippetSource) + replCompilerProxy.compileReplSnippet(compilationState, snippetSource, snippetId, compilationHistory) + .onSuccess { + runBlocking { + replEvaluator(it, currentEvalConfig) } - .onSuccess { - val snippetClass = it.returnValue.scriptClass - currentEvalConfig = ScriptEvaluationConfiguration(currentEvalConfig) { - previousSnippets.append(it.returnValue.scriptInstance) - if (snippetClass != null) { - jvm { - baseClassLoader(snippetClass.java.classLoader) - } + } + .onSuccess { + val snippetClass = it.returnValue.scriptClass + currentEvalConfig = ScriptEvaluationConfiguration(currentEvalConfig) { + previousSnippets.append(it.returnValue.scriptInstance) + if (snippetClass != null) { + jvm { + baseClassLoader(snippetClass.java.classLoader) } } - it.asSuccess() } - } + it.asSuccess() + } } +} - fun chechEvaluateInRepl( - compilationConfiguration: ScriptCompilationConfiguration, - evaluationConfiguration: ScriptEvaluationConfiguration, - snippets: Sequence, - expected: Sequence - ) { - val expectedIter = expected.iterator() - evaluateInRepl(compilationConfiguration, evaluationConfiguration, snippets).forEachIndexed { index, res -> - when (res) { - is ResultWithDiagnostics.Failure -> Assert.fail("#$index: Expected result, got $res") - is ResultWithDiagnostics.Success -> { - val expectedVal = expectedIter.next() - when (val resVal = res.value.returnValue) { - is ResultValue.Value -> Assert.assertEquals( - "#$index: Expected $expectedVal, got $resVal", - expectedVal, - resVal.value - ) - is ResultValue.Unit -> Assert.assertTrue("#$index: Expected $expectedVal, got Unit", expectedVal == null) - is ResultValue.Error -> Assert.assertTrue( - "#$index: Expected $expectedVal, got Error: ${resVal.error}", - expectedVal is Throwable && expectedVal.message == resVal.error.message - ) - else -> Assert.assertTrue("#$index: Expected $expectedVal, got unknown result $resVal", expectedVal == null) - } +fun chechEvaluateInRepl( + compilationConfiguration: ScriptCompilationConfiguration, + evaluationConfiguration: ScriptEvaluationConfiguration?, + snippets: Sequence, + expected: Sequence +) { + val expectedIter = expected.iterator() + evaluateInRepl(compilationConfiguration, evaluationConfiguration, snippets).forEachIndexed { index, res -> + when (res) { + is ResultWithDiagnostics.Failure -> Assert.fail("#$index: Expected result, got $res") + is ResultWithDiagnostics.Success -> { + val expectedVal = expectedIter.next() + when (val resVal = res.value.returnValue) { + is ResultValue.Value -> Assert.assertEquals( + "#$index: Expected $expectedVal, got $resVal", + expectedVal, + resVal.value + ) + is ResultValue.Unit -> Assert.assertTrue("#$index: Expected $expectedVal, got Unit", expectedVal == null) + is ResultValue.Error -> Assert.assertTrue( + "#$index: Expected $expectedVal, got Error: ${resVal.error}", + expectedVal is Throwable && expectedVal.message == resVal.error.message + ) + else -> Assert.assertTrue("#$index: Expected $expectedVal, got unknown result $resVal", expectedVal == null) } } } diff --git a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt index 5758950565f..028ec11c692 100644 --- a/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt +++ b/libraries/scripting/jvm-host-test/test/kotlin/script/experimental/jvmhost/test/ResolveDependenciesTest.kt @@ -6,7 +6,6 @@ package kotlin.script.experimental.jvmhost.test import junit.framework.TestCase -import org.junit.Ignore import org.junit.Test import java.io.File import kotlin.script.experimental.api.* @@ -30,15 +29,16 @@ class ResolveDependenciesTest : TestCase() { private val classAccessScript = "${thisPackage}.ShouldBeVisibleFromScript().x".toScriptSource() private val classImportScript = "import ${thisPackage}.ShouldBeVisibleFromScript\nShouldBeVisibleFromScript().x".toScriptSource() - private val funAndValAccessScript = - "$thisPackage.funShouldBeVisibleFromScript($thisPackage.valShouldBeVisibleFromScript)".toScriptSource() + val funAndValAccessScriptText = "$thisPackage.funShouldBeVisibleFromScript($thisPackage.valShouldBeVisibleFromScript)" + private val funAndValAccessScript = funAndValAccessScriptText.toScriptSource() - private val funAndValImportScript = + private val funAndValImportScriptText = """ import $thisPackage.funShouldBeVisibleFromScript import $thisPackage.valShouldBeVisibleFromScript funShouldBeVisibleFromScript(valShouldBeVisibleFromScript) - """.trimMargin().toScriptSource() + """.trimMargin() + private val funAndValImportScript = funAndValImportScriptText.toScriptSource() @Test fun testResolveClassFromClassloader() { @@ -53,12 +53,26 @@ class ResolveDependenciesTest : TestCase() { } @Test - // This doesn't work since there is no way to resolve a top-level function/property via reflection now (see #KT-33892) fun testResolveFunAndValFromClassloader() { runScriptAndCheckResult(funAndValAccessScript, configurationWithDependenciesFromClassloader, null, 42) runScriptAndCheckResult(funAndValImportScript, configurationWithDependenciesFromClassloader, null, 42) } + @Test + fun testReplResolveFunAndValFromClassloader() { + chechEvaluateInRepl( + configurationWithDependenciesFromClassloader, null, + sequenceOf(funAndValAccessScriptText, funAndValAccessScriptText), + sequenceOf(42, 42) + ) + chechEvaluateInRepl( + configurationWithDependenciesFromClassloader, null, + funAndValImportScriptText.split('\n').asSequence(), + sequenceOf(null, null, 42) + ) + runScriptAndCheckResult(funAndValImportScript, configurationWithDependenciesFromClassloader, null, 42) + } + @Test fun testResolveFunAndValFromClasspath() { runScriptAndCheckResult(funAndValAccessScript, configurationWithDependenciesFromClasspath, null, 42) @@ -105,7 +119,6 @@ class ResolveDependenciesTest : TestCase() { else -> throw Exception("Unexpected evaluation result: $res") } } - } @Suppress("unused") diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt index faea2b633af..0fd6f33a81b 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerImpl.kt @@ -103,6 +103,13 @@ class KJvmReplCompilerImpl(val hostConfiguration: ScriptingHostConfiguration) : messageCollector ) + if (history.isEmpty()) { + val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project) + ?.getScriptConfiguration(snippetKtFile)?.configuration + ?: context.baseScriptCompilationConfiguration + registerPackageFragmetProvidersIfNeeded(updatedConfiguration, context.environment) + } + val analysisResult = compilationState.analyzerEngine.analyzeReplLineWithImportedScripts(snippetKtFile, sourceFiles.drop(1), codeLine) AnalyzerWithCompilerReport.reportDiagnostics(analysisResult.diagnostics, errorHolder)