diff --git a/compiler/tests/org/jetbrains/kotlin/cli/LauncherReplTest.kt b/compiler/tests/org/jetbrains/kotlin/cli/LauncherReplTest.kt index dac3518a675..c073c3bae6e 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/LauncherReplTest.kt +++ b/compiler/tests/org/jetbrains/kotlin/cli/LauncherReplTest.kt @@ -8,6 +8,8 @@ package org.jetbrains.kotlin.cli import junit.framework.TestCase import org.jetbrains.kotlin.cli.common.CompilerSystemProperties import org.jetbrains.kotlin.test.TestCaseWithTmpdir +import org.jetbrains.kotlin.utils.KotlinPaths +import org.jetbrains.kotlin.utils.KotlinPathsFromHomeDir import org.jetbrains.kotlin.utils.PathUtil import org.junit.Assert import java.io.* @@ -19,7 +21,8 @@ class LauncherReplTest : TestCaseWithTmpdir() { private fun runInteractive( vararg inputsToExpectedOutputs: Pair, expectedExitCode: Int = 0, - workDirectory: File? = null + workDirectory: File? = null, + compilationClasspath: List = emptyList() ) { val javaExecutable = File(File(CompilerSystemProperties.JAVA_HOME.safeValue, "bin"), "java") @@ -31,8 +34,13 @@ class LauncherReplTest : TestCaseWithTmpdir() { if (workDirectory != null) { processBuilder.directory(workDirectory) } + if (compilationClasspath.isNotEmpty()) { + with(processBuilder.command()) { + add("-cp") + add(compilationClasspath.joinToString(File.pathSeparator) { it.absolutePath }) + } + } val process = processBuilder.start() - data class ExceptionContainer( var value: Throwable? = null ) @@ -170,4 +178,15 @@ class LauncherReplTest : TestCaseWithTmpdir() { "Z(42)" to "res5: Line_4\\.Z = Z\\(x=42\\)", ) } + + fun testReplWithClasspath() { + runInteractive( + *replOutHeader, + // access to any non-inlined object from the jarr passed to classpath shows that the classpath is supplied correctly + // both on compilation and on evaluation + "println(org.jetbrains.kotlin.allopen.AllOpenPluginNames.SUPPORTED_PRESETS.size >= 0)" to "true", + compilationClasspath = KotlinPathsFromHomeDir(PathUtil.kotlinPathsForDistDirectory.homePath) + .classPath(KotlinPaths.Jar.AllOpenPlugin) + ) + } } diff --git a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt index d8174bef786..a116bd1372a 100644 --- a/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt +++ b/plugins/scripting/scripting-compiler-impl/src/org/jetbrains/kotlin/scripting/definitions/ScriptDefinition.kt @@ -216,7 +216,11 @@ abstract class ScriptDefinition : UserDataHolderBase() { companion object { fun getDefault(hostConfiguration: ScriptingHostConfiguration) = - object : FromLegacy(hostConfiguration, StandardScriptDefinition) { + object : FromConfigurations( + hostConfiguration, + ScriptCompilationConfigurationFromDefinition(hostConfiguration, StandardScriptDefinition), + ScriptEvaluationConfigurationFromDefinition(hostConfiguration, StandardScriptDefinition) + ) { override val isDefault = true } } diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt index 6cd5288b39d..471c0818aca 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/KJvmReplCompilerBase.kt @@ -104,7 +104,7 @@ open class KJvmReplCompilerBase( // executing it on every snippet needs to be evaluated first if (state.history.isEmpty()) { val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project) - ?.getScriptConfiguration(snippetKtFile)?.configuration + ?.getScriptConfigurationResult(snippetKtFile, context.baseScriptCompilationConfiguration)?.valueOrNull()?.configuration ?: context.baseScriptCompilationConfiguration registerPackageFragmentProvidersIfNeeded( updatedConfiguration, @@ -166,7 +166,7 @@ open class KJvmReplCompilerBase( sourceFiles.first(), sourceDependencies ) { ktFile -> - dependenciesProvider?.getScriptConfiguration(ktFile)?.configuration + dependenciesProvider?.getScriptConfigurationResult(ktFile, context.baseScriptCompilationConfiguration)?.valueOrNull()?.configuration ?: context.baseScriptCompilationConfiguration }.onSuccess { compiledScript -> diff --git a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt index 50612206a14..0c835a306dc 100644 --- a/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt +++ b/plugins/scripting/scripting-compiler/src/org/jetbrains/kotlin/scripting/compiler/plugin/impl/ScriptJvmCompilerImpls.kt @@ -135,23 +135,25 @@ private fun compileImpl( val dependenciesProvider = ScriptDependenciesProvider.getInstance(context.environment.project) val getScriptConfiguration = { ktFile: KtFile -> - (dependenciesProvider?.getScriptConfiguration(ktFile)?.configuration ?: context.baseScriptCompilationConfiguration) - .with { - // Adjust definitions so all compiler dependencies are saved in the resulting compilation configuration, so evaluation - // performed with the expected classpath - // TODO: make this logic obsolete by injecting classpath earlier in the pipeline - val depsFromConfiguration = get(dependencies)?.flatMapTo(HashSet()) { (it as? JvmDependency)?.classpath ?: emptyList() } - val depsFromCompiler = context.environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS) - .mapNotNull { if (it is JvmClasspathRoot && !it.isSdkRoot) it.file else null } - if (!depsFromConfiguration.isNullOrEmpty()) { - val missingDeps = depsFromCompiler.filter { !depsFromConfiguration.contains(it) } - if (missingDeps.isNotEmpty()) { - dependencies.append(JvmDependency(missingDeps)) - } - } else { - dependencies.append(JvmDependency(depsFromCompiler)) + val refinedConfiguration = + dependenciesProvider?.getScriptConfigurationResult(ktFile, context.baseScriptCompilationConfiguration) + ?.valueOrNull()?.configuration ?: context.baseScriptCompilationConfiguration + refinedConfiguration.with { + // Adjust definitions so all compiler dependencies are saved in the resulting compilation configuration, so evaluation + // performed with the expected classpath + // TODO: make this logic obsolete by injecting classpath earlier in the pipeline + val depsFromConfiguration = get(dependencies)?.flatMapTo(HashSet()) { (it as? JvmDependency)?.classpath ?: emptyList() } + val depsFromCompiler = context.environment.configuration.getList(CLIConfigurationKeys.CONTENT_ROOTS) + .mapNotNull { if (it is JvmClasspathRoot && !it.isSdkRoot) it.file else null } + if (!depsFromConfiguration.isNullOrEmpty()) { + val missingDeps = depsFromCompiler.filter { !depsFromConfiguration.contains(it) } + if (missingDeps.isNotEmpty()) { + dependencies.append(JvmDependency(missingDeps)) } + } else { + dependencies.append(JvmDependency(depsFromCompiler)) } + } } return doCompile(context, script, sourceFiles, sourceDependencies, messageCollector, getScriptConfiguration)