Implement support for expression evaluation in jvm cli compiler
This commit is contained in:
+40
-15
@@ -10,8 +10,10 @@ import kotlinx.coroutines.runBlocking
|
||||
import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys
|
||||
import org.jetbrains.kotlin.cli.common.ExitCode
|
||||
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.extensions.ScriptEvaluationExtension
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
import org.jetbrains.kotlin.cli.common.messages.MessageCollector
|
||||
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.scripting.configuration.ScriptingConfigurationKeys
|
||||
@@ -19,6 +21,7 @@ import org.jetbrains.kotlin.scripting.definitions.ScriptDefinitionProvider
|
||||
import java.io.File
|
||||
import java.io.PrintStream
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.host.StringScriptSource
|
||||
import kotlin.script.experimental.host.toScriptSource
|
||||
|
||||
abstract class AbstractScriptEvaluationExtension : ScriptEvaluationExtension {
|
||||
@@ -46,37 +49,59 @@ abstract class AbstractScriptEvaluationExtension : ScriptEvaluationExtension {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Unable to process the script, scripting plugin is not configured")
|
||||
return ExitCode.COMPILATION_ERROR
|
||||
}
|
||||
val sourcePath = arguments.freeArgs.first()
|
||||
|
||||
setupScriptConfiguration(configuration)
|
||||
|
||||
val script = when {
|
||||
arguments is K2JVMCompilerArguments && arguments.expressions != null -> {
|
||||
StringScriptSource(arguments.expressions!!.joinToString("\n"), "script.kts")
|
||||
}
|
||||
arguments.script -> {
|
||||
val scriptFile = File(arguments.freeArgs.first())
|
||||
val script = scriptFile.toScriptSource()
|
||||
|
||||
if (scriptFile.isDirectory || !scriptDefinitionProvider.isScript(script)) {
|
||||
val extensionHint =
|
||||
if (configuration.get(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS)?.let { it.size == 1 && it.first().isDefault } == true) " (.kts)"
|
||||
else ""
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Specify path to the script file$extensionHint as the first argument")
|
||||
return ExitCode.COMPILATION_ERROR
|
||||
}
|
||||
script
|
||||
}
|
||||
else -> {
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Illegal set of arguments: either -script or -expression arguments expected at this point")
|
||||
return ExitCode.COMPILATION_ERROR
|
||||
}
|
||||
}
|
||||
|
||||
val environment = createEnvironment(projectEnvironment, configuration)
|
||||
|
||||
if (messageCollector.hasErrors()) return ExitCode.COMPILATION_ERROR
|
||||
|
||||
val scriptFile = File(sourcePath)
|
||||
val script = scriptFile.toScriptSource()
|
||||
|
||||
if (scriptFile.isDirectory || !scriptDefinitionProvider.isScript(script)) {
|
||||
val extensionHint =
|
||||
if (configuration.get(ScriptingConfigurationKeys.SCRIPT_DEFINITIONS)?.let { it.size == 1 && it.first().isDefault } == true) " (.kts)"
|
||||
else ""
|
||||
messageCollector.report(CompilerMessageSeverity.ERROR, "Specify path to the script file$extensionHint as the first argument")
|
||||
return ExitCode.COMPILATION_ERROR
|
||||
}
|
||||
|
||||
val definition = scriptDefinitionProvider.findDefinition(script) ?: scriptDefinitionProvider.getDefaultDefinition()
|
||||
|
||||
val scriptCompilationConfiguration = definition.compilationConfiguration
|
||||
|
||||
val scriptArgs =
|
||||
if (arguments.freeArgs.isNotEmpty()) arguments.freeArgs.subList(1, arguments.freeArgs.size)
|
||||
else emptyList<String>()
|
||||
if (arguments.script) arguments.freeArgs.subList(1, arguments.freeArgs.size)
|
||||
else arguments.freeArgs
|
||||
|
||||
val evaluationConfiguration = definition.evaluationConfiguration.with {
|
||||
constructorArgs(scriptArgs.toTypedArray())
|
||||
platformEvaluationConfiguration()
|
||||
|
||||
}
|
||||
val scriptCompilationConfiguration = definition.compilationConfiguration
|
||||
return doEval(script, scriptCompilationConfiguration, evaluationConfiguration, environment, messageCollector)
|
||||
}
|
||||
|
||||
private fun doEval(
|
||||
script: SourceCode,
|
||||
scriptCompilationConfiguration: ScriptCompilationConfiguration,
|
||||
evaluationConfiguration: ScriptEvaluationConfiguration,
|
||||
environment: KotlinCoreEnvironment,
|
||||
messageCollector: MessageCollector
|
||||
): ExitCode {
|
||||
val scriptCompiler = createScriptCompiler(environment)
|
||||
|
||||
return runBlocking {
|
||||
|
||||
+3
-2
@@ -13,7 +13,8 @@ import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
|
||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||
import org.jetbrains.kotlin.config.JVMConfigurationKeys
|
||||
import org.jetbrains.kotlin.scripting.compiler.plugin.impl.ScriptJvmCompilerFromEnvironment
|
||||
import kotlin.script.experimental.api.*
|
||||
import kotlin.script.experimental.api.ScriptEvaluationConfiguration
|
||||
import kotlin.script.experimental.api.ScriptEvaluator
|
||||
import kotlin.script.experimental.jvm.BasicJvmScriptEvaluator
|
||||
import kotlin.script.experimental.jvm.baseClassLoader
|
||||
import kotlin.script.experimental.jvm.jvm
|
||||
@@ -46,6 +47,6 @@ class JvmCliScriptEvaluationExtension : AbstractScriptEvaluationExtension() {
|
||||
}
|
||||
|
||||
override fun isAccepted(arguments: CommonCompilerArguments): Boolean =
|
||||
arguments is K2JVMCompilerArguments && arguments.script
|
||||
arguments is K2JVMCompilerArguments && (arguments.script || arguments.expressions != null)
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -6,7 +6,6 @@
|
||||
package org.jetbrains.kotlin.scripting.compiler.plugin.impl
|
||||
|
||||
import org.jetbrains.kotlin.cli.common.arguments.Argument
|
||||
import org.jetbrains.kotlin.cli.common.arguments.ArgumentParseErrors
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageLocation
|
||||
import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity
|
||||
@@ -100,6 +99,7 @@ internal fun reportArgumentsIgnoredGenerally(
|
||||
K2JVMCompilerArguments::commonSources,
|
||||
K2JVMCompilerArguments::allWarningsAsErrors,
|
||||
K2JVMCompilerArguments::script,
|
||||
K2JVMCompilerArguments::expressions,
|
||||
K2JVMCompilerArguments::scriptTemplates,
|
||||
K2JVMCompilerArguments::scriptResolverEnvironment,
|
||||
K2JVMCompilerArguments::disableStandardScript,
|
||||
|
||||
+15
@@ -46,6 +46,21 @@ class ScriptingWithCliCompilerTest {
|
||||
)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testExpression() {
|
||||
runWithK2JVMCompiler(
|
||||
arrayOf(
|
||||
"-expression",
|
||||
"val x = 7; println(x * 6); for (arg in args) println(arg)",
|
||||
"--",
|
||||
"hi",
|
||||
"there"
|
||||
),
|
||||
listOf("42", "hi", "there")
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
private fun getMainKtsClassPath(): List<File> {
|
||||
return listOf(
|
||||
File("dist/kotlinc/lib/kotlin-main-kts.jar").also {
|
||||
|
||||
+13
-2
@@ -112,15 +112,26 @@ fun runWithK2JVMCompiler(
|
||||
add("-script")
|
||||
add(scriptPath)
|
||||
}
|
||||
runWithK2JVMCompiler(args.toTypedArray(), expectedOutPatterns, expectedExitCode)
|
||||
}
|
||||
|
||||
fun runWithK2JVMCompiler(
|
||||
args: Array<String>,
|
||||
expectedOutPatterns: List<String> = emptyList(),
|
||||
expectedExitCode: Int = 0
|
||||
) {
|
||||
val (out, err, ret) = captureOutErrRet {
|
||||
CLITool.doMainNoExit(
|
||||
K2JVMCompiler(),
|
||||
args.toTypedArray()
|
||||
args
|
||||
)
|
||||
}
|
||||
try {
|
||||
val outLines = out.lines()
|
||||
Assert.assertEquals(expectedOutPatterns.size, outLines.size)
|
||||
Assert.assertEquals(
|
||||
"Expecting pattern:\n ${expectedOutPatterns.joinToString("\n ")}\nGot:\n ${outLines.joinToString("\n ")}",
|
||||
expectedOutPatterns.size, outLines.size
|
||||
)
|
||||
for ((expectedPattern, actualLine) in expectedOutPatterns.zip(outLines)) {
|
||||
Assert.assertTrue(
|
||||
"line \"$actualLine\" do not match with expected pattern \"$expectedPattern\"",
|
||||
|
||||
Reference in New Issue
Block a user