Implement -X arguments passing from kotlin runner to compiler

This commit is contained in:
Ilya Chernikov
2021-01-04 13:06:18 +01:00
parent 9a7d1948a7
commit d2ecc1e361
6 changed files with 52 additions and 16 deletions
@@ -42,6 +42,7 @@ object Main {
var collectingExpressions = false var collectingExpressions = false
var needsCompiler = false var needsCompiler = false
val arguments = arrayListOf<String>() val arguments = arrayListOf<String>()
val compilerArguments = arrayListOf<String>()
var expression: String? = null var expression: String? = null
var noReflect = false var noReflect = false
@@ -103,6 +104,10 @@ object Main {
} }
else if ("-no-reflect" == arg) { else if ("-no-reflect" == arg) {
noReflect = true noReflect = true
compilerArguments.add(arg)
}
else if (arg.startsWith("-X")) {
compilerArguments.add(arg)
} }
else if (arg.startsWith("-")) { else if (arg.startsWith("-")) {
throw RunnerException("unsupported argument: $arg") throw RunnerException("unsupported argument: $arg")
@@ -146,7 +151,7 @@ object Main {
} }
} }
runner.run(classpath, arguments, compilerClasspath) runner.run(classpath, compilerArguments, arguments, compilerClasspath)
} }
private fun MutableList<URL>.addPath(path: String) { private fun MutableList<URL>.addPath(path: String) {
@@ -167,19 +172,21 @@ object Main {
private fun printUsageAndExit() { private fun printUsageAndExit() {
println("""kotlin: run Kotlin programs, scripts or REPL. println("""kotlin: run Kotlin programs, scripts or REPL.
Usage: kotlin <options> <command> <arguments> Usage: kotlin <options> <command> [<arguments>]
where command may be one of: where command may be one of:
foo.Bar Runs the 'main' function from the class with the given qualified name foo.Bar Runs the 'main' function from the class with the given qualified name
(compiler arguments are ignored)
app.jar Runs the given JAR file as 'java -jar' would do app.jar Runs the given JAR file as 'java -jar' would do
(-classpath argument is ignored and no Kotlin runtime is added to the classpath) (compiler arguments are ignored and no Kotlin stdlib is added to the classpath)
""" + script.kts Compiles and runs the given script, passing <arguments> to it
// script.kts Compiles and runs the given script -expression (-e) '2+2' Evaluates the expression and prints the result, passing <arguments> to it
// -expression (-e) '2+2' Evaluates the expression and prints the result <no command> Runs Kotlin REPL, passing <arguments> to it
"""and possible options include: and possible options include:
-classpath (-cp) <path> Paths where to find user class files -classpath (-cp) <path> Paths where to find user class files
-Dname=value Set a system JVM property -Dname=value Set a system JVM property
-J<option> Pass an option directly to JVM -J<option> Pass an option directly to JVM
-no-reflect Don't include Kotlin reflection implementation into classpath -no-reflect Don't include Kotlin reflection implementation into classpath
-X<flag>[=value] Pass -X argument to the compiler
-version Display Kotlin version -version Display Kotlin version
-help (-h) Print a synopsis of options -help (-h) Print a synopsis of options
""") """)
@@ -21,6 +21,7 @@ import java.net.URL
interface Runner { interface Runner {
fun run( fun run(
classpath: List<URL>, classpath: List<URL>,
compilerArguments: List<String>,
arguments: List<String>, arguments: List<String>,
compilerClasspath: List<URL> compilerClasspath: List<URL>
) )
@@ -32,7 +32,7 @@ abstract class AbstractRunner : Runner {
protected abstract fun createClassLoader(classpath: List<URL>): ClassLoader protected abstract fun createClassLoader(classpath: List<URL>): ClassLoader
override fun run(classpath: List<URL>, arguments: List<String>, compilerClasspath: List<URL>) { override fun run(classpath: List<URL>, compilerArguments: List<String>, arguments: List<String>, compilerClasspath: List<URL>) {
val classLoader = createClassLoader(classpath) val classLoader = createClassLoader(classpath)
val mainClass = try { val mainClass = try {
@@ -128,17 +128,19 @@ private fun MutableList<String>.addClasspathArgIfNeeded(classpath: List<URL>) {
} }
class ReplRunner : RunnerWithCompiler() { class ReplRunner : RunnerWithCompiler() {
override fun run(classpath: List<URL>, arguments: List<String>, compilerClasspath: List<URL>) { override fun run(classpath: List<URL>, compilerArguments: List<String>, arguments: List<String>, compilerClasspath: List<URL>) {
val compilerArgs = ArrayList<String>() val compilerArgs = ArrayList<String>()
compilerArgs.addClasspathArgIfNeeded(classpath) compilerArgs.addClasspathArgIfNeeded(classpath)
compilerArgs.addAll(compilerArguments)
runCompiler(compilerClasspath, compilerArgs) runCompiler(compilerClasspath, compilerArgs)
} }
} }
class ScriptRunner(private val path: String) : RunnerWithCompiler() { class ScriptRunner(private val path: String) : RunnerWithCompiler() {
override fun run(classpath: List<URL>, arguments: List<String>, compilerClasspath: List<URL>) { override fun run(classpath: List<URL>, compilerArguments: List<String>, arguments: List<String>, compilerClasspath: List<URL>) {
val compilerArgs = ArrayList<String>().apply { val compilerArgs = ArrayList<String>().apply {
addClasspathArgIfNeeded(classpath) addClasspathArgIfNeeded(classpath)
addAll(compilerArguments)
add("-script") add("-script")
add(path) add(path)
if (arguments.isNotEmpty() && arguments.first() != "--") { if (arguments.isNotEmpty() && arguments.first() != "--") {
@@ -151,9 +153,10 @@ class ScriptRunner(private val path: String) : RunnerWithCompiler() {
} }
class ExpressionRunner(private val code: String) : RunnerWithCompiler() { class ExpressionRunner(private val code: String) : RunnerWithCompiler() {
override fun run(classpath: List<URL>, arguments: List<String>, compilerClasspath: List<URL>) { override fun run(classpath: List<URL>, compilerArguments: List<String>, arguments: List<String>, compilerClasspath: List<URL>) {
val compilerArgs = ArrayList<String>().apply { val compilerArgs = ArrayList<String>().apply {
addClasspathArgIfNeeded(classpath) addClasspathArgIfNeeded(classpath)
addAll(compilerArguments)
add("-expression") add("-expression")
add(code) add(code)
if (arguments.isNotEmpty() && arguments.first() != "--") { if (arguments.isNotEmpty() && arguments.first() != "--") {
+4
View File
@@ -0,0 +1,4 @@
fun f() : Result<Int> = Result.success(42)
println(f().getOrNull())
@@ -24,6 +24,7 @@ import kotlin.io.FilesKt;
import kotlin.io.path.PathsKt; import kotlin.io.path.PathsKt;
import kotlin.text.Charsets; import kotlin.text.Charsets;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.checkers.ThirdPartyAnnotationPathsKt; import org.jetbrains.kotlin.checkers.ThirdPartyAnnotationPathsKt;
import org.jetbrains.kotlin.cli.common.CLITool; import org.jetbrains.kotlin.cli.common.CLITool;
import org.jetbrains.kotlin.cli.common.ExitCode; import org.jetbrains.kotlin.cli.common.ExitCode;
@@ -82,7 +83,7 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir {
} }
@NotNull @NotNull
public static String getNormalizedCompilerOutput(@NotNull String pureOutput, @NotNull ExitCode exitCode, @NotNull String testDataDir) { public static String getNormalizedCompilerOutput(@NotNull String pureOutput, @Nullable ExitCode exitCode, @NotNull String testDataDir) {
String testDataAbsoluteDir = new File(testDataDir).getAbsolutePath(); String testDataAbsoluteDir = new File(testDataDir).getAbsolutePath();
String normalizedOutputWithoutExitCode = StringUtil.convertLineSeparators(pureOutput) String normalizedOutputWithoutExitCode = StringUtil.convertLineSeparators(pureOutput)
.replace(testDataAbsoluteDir, TESTDATA_DIR) .replace(testDataAbsoluteDir, TESTDATA_DIR)
@@ -96,7 +97,7 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir {
.replace("\n" + Usage.BAT_DELIMITER_CHARACTERS_NOTE + "\n", "") .replace("\n" + Usage.BAT_DELIMITER_CHARACTERS_NOTE + "\n", "")
.replaceAll("log4j:WARN.*\n", ""); .replaceAll("log4j:WARN.*\n", "");
return normalizedOutputWithoutExitCode + exitCode + "\n"; return exitCode == null ? normalizedOutputWithoutExitCode : (normalizedOutputWithoutExitCode + exitCode + "\n");
} }
private void doTest(@NotNull String fileName, @NotNull CLITool<?> compiler) { private void doTest(@NotNull String fileName, @NotNull CLITool<?> compiler) {
@@ -48,9 +48,16 @@ class LauncherScriptTest : TestCaseWithTmpdir() {
) )
pb.directory(workDirectory) pb.directory(workDirectory)
val process = pb.start() val process = pb.start()
val stdout = StringUtil.convertLineSeparators(process.inputStream.bufferedReader().use { it.readText() }) val stdout =
val stderr = StringUtil.convertLineSeparators(process.errorStream.bufferedReader().use { it.readText() }) AbstractCliTest.getNormalizedCompilerOutput(
.replace("Picked up [_A-Z]+:.*\n".toRegex(), "") StringUtil.convertLineSeparators(process.inputStream.bufferedReader().use { it.readText() }),
null, testDataDirectory
)
val stderr =
AbstractCliTest.getNormalizedCompilerOutput(
StringUtil.convertLineSeparators(process.errorStream.bufferedReader().use { it.readText() }),
null, testDataDirectory
).replace("Picked up [_A-Z]+:.*\n".toRegex(), "")
process.waitFor(10, TimeUnit.SECONDS) process.waitFor(10, TimeUnit.SECONDS)
val exitCode = process.exitValue() val exitCode = process.exitValue()
try { try {
@@ -228,6 +235,19 @@ class LauncherScriptTest : TestCaseWithTmpdir() {
runProcess("kotlin", "LegacyAssertEnabledKt", "-J-ea:kotlin._Assertions", workDirectory = tmpdir) runProcess("kotlin", "LegacyAssertEnabledKt", "-J-ea:kotlin._Assertions", workDirectory = tmpdir)
} }
fun testScriptWithXArguments() {
runProcess(
"kotlin", "$testDataDirectory/funWithResultReturn.kts",
expectedExitCode = 1,
expectedStderr = """error: 'kotlin.Result' cannot be used as a return type (funWithResultReturn.kts:2:11)
compiler/testData/launcher/funWithResultReturn.kts:2:11: error: 'kotlin.Result' cannot be used as a return type
fun f() : Result<Int> = Result.success(42)
^
"""
)
runProcess("kotlin", "-Xallow-result-return-type", "$testDataDirectory/funWithResultReturn.kts", expectedStdout = "42\n")
}
fun testProperty() { fun testProperty() {
runProcess("kotlinc", "$testDataDirectory/property.kt", "-d", tmpdir.path) runProcess("kotlinc", "$testDataDirectory/property.kt", "-d", tmpdir.path)