Support -Xargfile in all scenarios; refactor & prettify code
Perform command line argument preprocessing in the beginning of
parseCommandLineArguments, so that argfiles are expanded in all
scenarios, not just when the compiler is invoked via
K2{JVM,JS}Compiler.exec
This commit is contained in:
committed by
Dmitry Savvinov
parent
43467516ef
commit
61902e1fd5
+6
-1
@@ -54,11 +54,16 @@ data class ArgumentParseErrors(
|
||||
|
||||
var argumentWithoutValue: String? = null,
|
||||
|
||||
val argfileErrors: MutableList<String> = SmartList<String>()
|
||||
val argfileErrors: MutableList<String> = SmartList()
|
||||
)
|
||||
|
||||
// Parses arguments into the passed [result] object. Errors related to the parsing will be collected into [CommonToolArguments.errors].
|
||||
fun <A : CommonToolArguments> parseCommandLineArguments(args: List<String>, result: A) {
|
||||
val preprocessed = preprocessCommandLineArguments(args, result.errors)
|
||||
parsePreprocessedCommandLineArguments(preprocessed, result)
|
||||
}
|
||||
|
||||
private fun <A : CommonToolArguments> parsePreprocessedCommandLineArguments(args: List<String>, result: A) {
|
||||
data class ArgumentField(val property: KMutableProperty1<A, Any?>, val argument: Argument)
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
|
||||
+17
-14
@@ -5,39 +5,42 @@
|
||||
|
||||
package org.jetbrains.kotlin.cli.common.arguments
|
||||
|
||||
import java.io.*
|
||||
import java.nio.charset.StandardCharsets
|
||||
import java.io.File
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.Reader
|
||||
|
||||
private val experimentalArgfileArgument = "-Xargfile"
|
||||
private val QUOTATION_MARK = '"'
|
||||
private val BACKSLASH = '\\'
|
||||
private val WHITESPACE = ' '
|
||||
private val NEWLINE = '\n'
|
||||
private const val EXPERIMENTAL_ARGFILE_ARGUMENT = "-Xargfile"
|
||||
|
||||
private const val QUOTATION_MARK = '"'
|
||||
private const val BACKSLASH = '\\'
|
||||
private const val WHITESPACE = ' '
|
||||
private const val NEWLINE = '\n'
|
||||
|
||||
/**
|
||||
* Performs initial preprocessing of arguments, passed to the compiler.
|
||||
* This is done prior to *any* arguments parsing, and result of preprocessing
|
||||
* will be used instead of actual passed arguments.
|
||||
*/
|
||||
fun <A : CommonToolArguments> preprocessCommandLineArguments(args: List<String>, result: A): List<String> =
|
||||
internal fun preprocessCommandLineArguments(args: List<String>, errors: ArgumentParseErrors): List<String> =
|
||||
args.flatMap {
|
||||
if (it.isArgumentForArgfile)
|
||||
File(it.argfilePath).expand(result)
|
||||
File(it.argfilePath).expand(errors)
|
||||
else
|
||||
listOf(it)
|
||||
}
|
||||
|
||||
private fun <A : CommonToolArguments> File.expand(result: A): List<String> {
|
||||
private fun File.expand(errors: ArgumentParseErrors): List<String> {
|
||||
return try {
|
||||
bufferedReader(Charsets.UTF_8).use {
|
||||
generateSequence { it.parseNextArgument() }.toList()
|
||||
}
|
||||
} catch (e: FileNotFoundException) {
|
||||
// Process FNFE separately to render absolutePath in error message
|
||||
result.errors.argfileErrors += "Argfile not found: $absolutePath"
|
||||
errors.argfileErrors += "Argfile not found: $absolutePath"
|
||||
emptyList()
|
||||
} catch (e: IOException) {
|
||||
result.errors.argfileErrors += "Error while reading argfile: $e"
|
||||
errors.argfileErrors += "Error while reading argfile: $e"
|
||||
emptyList()
|
||||
}
|
||||
}
|
||||
@@ -69,9 +72,9 @@ private fun Reader.consumeRestOfEscapedSequence(sb: StringBuilder) {
|
||||
}
|
||||
|
||||
private val String.argfilePath: String
|
||||
get() = removePrefix("$experimentalArgfileArgument=")
|
||||
get() = removePrefix("$EXPERIMENTAL_ARGFILE_ARGUMENT=")
|
||||
|
||||
// Note that currently we use only experimental syntax for passing argfiles
|
||||
// In 1.3 we can support also javac-like syntax `@argfile`
|
||||
private val String.isArgumentForArgfile: Boolean
|
||||
get() = startsWith("$experimentalArgfileArgument=")
|
||||
get() = startsWith("$EXPERIMENTAL_ARGFILE_ARGUMENT=")
|
||||
|
||||
@@ -41,8 +41,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
args: Array<out String>
|
||||
): ExitCode {
|
||||
val arguments = createArguments()
|
||||
val preprocessedArguments = preprocessCommandLineArguments(args.asList(), arguments)
|
||||
parseCommandLineArguments(preprocessedArguments, arguments)
|
||||
parseCommandLineArguments(args.asList(), arguments)
|
||||
val collector = PrintingMessageCollector(errStream, messageRenderer, arguments.verbose)
|
||||
|
||||
try {
|
||||
@@ -106,8 +105,7 @@ abstract class CLITool<A : CommonToolArguments> {
|
||||
|
||||
// Used in kotlin-maven-plugin (KotlinCompileMojoBase) and in kotlin-gradle-plugin (KotlinJvmOptionsImpl, KotlinJsOptionsImpl)
|
||||
fun parseArguments(args: Array<out String>, arguments: A) {
|
||||
val preprocessed = preprocessCommandLineArguments(args.asList(), arguments)
|
||||
parseCommandLineArguments(preprocessed, arguments)
|
||||
parseCommandLineArguments(args.asList(), arguments)
|
||||
val message = validateArguments(arguments.errors)
|
||||
if (message != null) {
|
||||
throw IllegalArgumentException(message)
|
||||
|
||||
Reference in New Issue
Block a user