Change format of -X arguments to require value after '='

Report a warning when an argument is passed in the old form (with the
whitespace)

 #KT-17264 Fixed
This commit is contained in:
Alexander Udalov
2017-04-05 16:42:43 +03:00
parent 78c0111c6e
commit f4b6db4dc0
22 changed files with 100 additions and 73 deletions
@@ -104,6 +104,9 @@ public abstract class CommonCompilerArguments implements Serializable {
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")
public List<String> extraArgumentsPassedInObsoleteForm = new SmartList<>();
@NotNull
public static CommonCompilerArguments createDefaultInstance() {
DummyImpl arguments = new DummyImpl();
@@ -22,16 +22,15 @@ import java.util.*
@JvmOverloads
fun <A : CommonCompilerArguments> parseArguments(args: Array<String>, arguments: A, ignoreInvalidArguments: Boolean = false) {
val unparsedArgs = parseCommandLineArguments(args, arguments)
val (unknownExtraArgs, unknownArgs) = unparsedArgs.partition { it.startsWith("-X") }
arguments.unknownExtraFlags = unknownExtraArgs
arguments.freeArgs = if (ignoreInvalidArguments) unknownArgs.filterNot { it.startsWith("-") } else unknownArgs
parseCommandLineArguments(args, arguments)
if (!ignoreInvalidArguments) {
for (argument in unknownArgs) {
if (argument.startsWith("-")) {
throw IllegalArgumentException("Invalid argument: " + argument)
}
if (ignoreInvalidArguments) {
arguments.freeArgs.removeAll { it.startsWith("-") }
}
for (argument in arguments.freeArgs) {
if (argument.startsWith("-")) {
throw IllegalArgumentException("Invalid argument: " + argument)
}
}
}
@@ -26,41 +26,56 @@ annotation class Argument(
)
val Argument.isAdvanced: Boolean
get() = value.startsWith("-X") && value.length > 2
get() = value.startsWith(ADVANCED_ARGUMENT_PREFIX) && value.length > ADVANCED_ARGUMENT_PREFIX.length
fun <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>, result: A): List<String> {
data class ArgumentField(val field: Field, val argumentNames: List<String>)
private val ADVANCED_ARGUMENT_PREFIX = "-X"
fun <A : CommonCompilerArguments> parseCommandLineArguments(args: Array<String>, result: A) {
data class ArgumentField(val field: Field, val argument: Argument)
val fields = result::class.java.fields.mapNotNull { field ->
val argument = field.getAnnotation(Argument::class.java)
if (argument != null)
ArgumentField(field, listOfNotNull(argument.value, argument.shortName.takeUnless(String::isEmpty)))
else null
if (argument != null) ArgumentField(field, argument) else null
}
val freeArgs = mutableListOf<String>()
var i = 0
while (i < args.size) {
val arg = args[i++]
val field = fields.firstOrNull { (_, names) -> arg in names }?.field
if (field == null) {
freeArgs.add(arg)
val argumentField = fields.firstOrNull { (_, argument) ->
argument.value == arg ||
argument.shortName.takeUnless(String::isEmpty) == arg ||
(argument.isAdvanced && arg.startsWith(argument.value + "="))
}
if (argumentField == null) {
if (arg.startsWith(ADVANCED_ARGUMENT_PREFIX)) {
result.unknownExtraFlags.add(arg)
}
else {
result.freeArgs.add(arg)
}
continue
}
val value: Any =
if (field.type == Boolean::class.java) true
else {
if (i == args.size) {
throw IllegalArgumentException("No value passed for argument $arg")
}
args[i++]
val (field, argument) = argumentField
val value: Any = when {
field.type == Boolean::class.java -> true
argument.isAdvanced && arg.startsWith(argument.value + "=") -> {
arg.substring(argument.value.length + 1)
}
else -> {
if (i == args.size) {
throw IllegalArgumentException("No value passed for argument $arg")
}
if (argument.isAdvanced) {
result.extraArgumentsPassedInObsoleteForm.add(arg)
}
args[i++]
}
}
updateField(field, result, value)
}
return freeArgs
}
private fun <A : CommonCompilerArguments> updateField(field: Field, result: A, value: Any) {