Scripting: switch default definition to new scheme

also correctly pass externaly provided configuration on compilation
and evaluation.
Fixes REPL evaluation with dependencies passed via compilation classpath.
This commit is contained in:
Ilya Chernikov
2022-06-22 15:26:32 +02:00
parent 46c769deb6
commit 8bc43917ec
4 changed files with 45 additions and 20 deletions
@@ -8,6 +8,8 @@ package org.jetbrains.kotlin.cli
import junit.framework.TestCase import junit.framework.TestCase
import org.jetbrains.kotlin.cli.common.CompilerSystemProperties import org.jetbrains.kotlin.cli.common.CompilerSystemProperties
import org.jetbrains.kotlin.test.TestCaseWithTmpdir 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.jetbrains.kotlin.utils.PathUtil
import org.junit.Assert import org.junit.Assert
import java.io.* import java.io.*
@@ -19,7 +21,8 @@ class LauncherReplTest : TestCaseWithTmpdir() {
private fun runInteractive( private fun runInteractive(
vararg inputsToExpectedOutputs: Pair<String?, String>, vararg inputsToExpectedOutputs: Pair<String?, String>,
expectedExitCode: Int = 0, expectedExitCode: Int = 0,
workDirectory: File? = null workDirectory: File? = null,
compilationClasspath: List<File> = emptyList()
) { ) {
val javaExecutable = File(File(CompilerSystemProperties.JAVA_HOME.safeValue, "bin"), "java") val javaExecutable = File(File(CompilerSystemProperties.JAVA_HOME.safeValue, "bin"), "java")
@@ -31,8 +34,13 @@ class LauncherReplTest : TestCaseWithTmpdir() {
if (workDirectory != null) { if (workDirectory != null) {
processBuilder.directory(workDirectory) processBuilder.directory(workDirectory)
} }
if (compilationClasspath.isNotEmpty()) {
with(processBuilder.command()) {
add("-cp")
add(compilationClasspath.joinToString(File.pathSeparator) { it.absolutePath })
}
}
val process = processBuilder.start() val process = processBuilder.start()
data class ExceptionContainer( data class ExceptionContainer(
var value: Throwable? = null var value: Throwable? = null
) )
@@ -170,4 +178,15 @@ class LauncherReplTest : TestCaseWithTmpdir() {
"Z(42)" to "res5: Line_4\\.Z = Z\\(x=42\\)", "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)
)
}
} }
@@ -216,7 +216,11 @@ abstract class ScriptDefinition : UserDataHolderBase() {
companion object { companion object {
fun getDefault(hostConfiguration: ScriptingHostConfiguration) = fun getDefault(hostConfiguration: ScriptingHostConfiguration) =
object : FromLegacy(hostConfiguration, StandardScriptDefinition) { object : FromConfigurations(
hostConfiguration,
ScriptCompilationConfigurationFromDefinition(hostConfiguration, StandardScriptDefinition),
ScriptEvaluationConfigurationFromDefinition(hostConfiguration, StandardScriptDefinition)
) {
override val isDefault = true override val isDefault = true
} }
} }
@@ -104,7 +104,7 @@ open class KJvmReplCompilerBase<AnalyzerT : ReplCodeAnalyzerBase>(
// executing it on every snippet needs to be evaluated first // executing it on every snippet needs to be evaluated first
if (state.history.isEmpty()) { if (state.history.isEmpty()) {
val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project) val updatedConfiguration = ScriptDependenciesProvider.getInstance(context.environment.project)
?.getScriptConfiguration(snippetKtFile)?.configuration ?.getScriptConfigurationResult(snippetKtFile, context.baseScriptCompilationConfiguration)?.valueOrNull()?.configuration
?: context.baseScriptCompilationConfiguration ?: context.baseScriptCompilationConfiguration
registerPackageFragmentProvidersIfNeeded( registerPackageFragmentProvidersIfNeeded(
updatedConfiguration, updatedConfiguration,
@@ -166,7 +166,7 @@ open class KJvmReplCompilerBase<AnalyzerT : ReplCodeAnalyzerBase>(
sourceFiles.first(), sourceFiles.first(),
sourceDependencies sourceDependencies
) { ktFile -> ) { ktFile ->
dependenciesProvider?.getScriptConfiguration(ktFile)?.configuration dependenciesProvider?.getScriptConfigurationResult(ktFile, context.baseScriptCompilationConfiguration)?.valueOrNull()?.configuration
?: context.baseScriptCompilationConfiguration ?: context.baseScriptCompilationConfiguration
}.onSuccess { compiledScript -> }.onSuccess { compiledScript ->
@@ -135,8 +135,10 @@ private fun compileImpl(
val dependenciesProvider = ScriptDependenciesProvider.getInstance(context.environment.project) val dependenciesProvider = ScriptDependenciesProvider.getInstance(context.environment.project)
val getScriptConfiguration = { ktFile: KtFile -> val getScriptConfiguration = { ktFile: KtFile ->
(dependenciesProvider?.getScriptConfiguration(ktFile)?.configuration ?: context.baseScriptCompilationConfiguration) val refinedConfiguration =
.with { 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 // Adjust definitions so all compiler dependencies are saved in the resulting compilation configuration, so evaluation
// performed with the expected classpath // performed with the expected classpath
// TODO: make this logic obsolete by injecting classpath earlier in the pipeline // TODO: make this logic obsolete by injecting classpath earlier in the pipeline