CLI: use "--" to separate free arguments from compiler options

#KT-9370 Fixed
This commit is contained in:
Alexander Udalov
2017-04-10 12:53:09 +03:00
parent baef649fe4
commit 8aba862e97
6 changed files with 36 additions and 13 deletions
@@ -109,6 +109,8 @@ public abstract class CommonCompilerArguments implements Serializable {
public List<String> freeArgs = new SmartList<>();
public List<String> unknownArgs = new SmartList<>();
public List<String> unknownExtraFlags = new SmartList<>();
// Names of extra (-X...) arguments which have been passed in an obsolete form ("-Xaaa bbb", instead of "-Xaaa=bbb")
@@ -24,14 +24,9 @@ import java.util.*
fun <A : CommonCompilerArguments> parseArguments(args: Array<String>, arguments: A, ignoreInvalidArguments: Boolean = false) {
parseCommandLineArguments(args, arguments)
if (ignoreInvalidArguments) {
arguments.freeArgs.removeAll { it.startsWith("-") }
}
for (argument in arguments.freeArgs) {
if (argument.startsWith("-")) {
throw IllegalArgumentException("Invalid argument: " + argument)
}
val invalidArgument = arguments.unknownArgs.firstOrNull()?.takeUnless { ignoreInvalidArguments }
if (invalidArgument != null) {
throw IllegalArgumentException("Invalid argument: $invalidArgument")
}
}
@@ -30,6 +30,7 @@ val Argument.isAdvanced: Boolean
get() = value.startsWith(ADVANCED_ARGUMENT_PREFIX) && value.length > ADVANCED_ARGUMENT_PREFIX.length
private val ADVANCED_ARGUMENT_PREFIX = "-X"
private val FREE_ARGS_DELIMITER = "--"
// Parses arguments in the passed [result] object, or throws an [IllegalArgumentException] with the message to be displayed to the user
fun <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>, result: A) {
@@ -41,10 +42,21 @@ fun <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>,
}
val visitedArgs = mutableSetOf<String>()
var freeArgsStarted = false
var i = 0
while (i < args.size) {
val arg = args[i++]
if (freeArgsStarted) {
result.freeArgs.add(arg)
continue
}
if (arg == FREE_ARGS_DELIMITER) {
freeArgsStarted = true
continue
}
val argumentField = fields.firstOrNull { (_, argument) ->
argument.value == arg ||
argument.shortName.takeUnless(String::isEmpty) == arg ||
@@ -52,11 +64,10 @@ fun <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>,
}
if (argumentField == null) {
if (arg.startsWith(ADVANCED_ARGUMENT_PREFIX)) {
result.unknownExtraFlags.add(arg)
}
else {
result.freeArgs.add(arg)
when {
arg.startsWith(ADVANCED_ARGUMENT_PREFIX) -> result.unknownExtraFlags.add(arg)
arg.startsWith("-") -> result.unknownArgs.add(arg)
else -> result.freeArgs.add(arg)
}
continue
}
@@ -0,0 +1,8 @@
OUT:
hi
-name
Marty
--
there
Return code: 0
@@ -0,0 +1,3 @@
for (arg in args) {
println(arg)
}
@@ -57,6 +57,10 @@ public class CompilerSmokeTest extends CompilerSmokeTestBase {
runCompiler("script", "-script", "script.kts", "hi", "there");
}
public void testScriptDashedArgs() throws Exception {
runCompiler("script", "-script", "script.kts", "--", "hi", "-name", "Marty", "--", "there");
}
public void testScriptWithClasspath() throws Exception {
runCompiler("script", "-cp", new File("lib/javax.inject.jar").getAbsolutePath(), "-script", "script.kts");
}