diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt index d48578b6b9d..80c981ddd8e 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/preprocessCommandLineArguments.kt @@ -10,7 +10,8 @@ import java.io.FileNotFoundException import java.io.IOException import java.io.Reader -private const val EXPERIMENTAL_ARGFILE_ARGUMENT = "-Xargfile" +const val ARGFILE_ARGUMENT = "@" +private const val EXPERIMENTAL_ARGFILE_ARGUMENT = "-Xargfile=" private const val SINGLE_QUOTE = '\'' private const val DOUBLE_QUOTE = '"' @@ -24,11 +25,16 @@ private const val NEWLINE = '\n' * will be used instead of actual passed arguments. */ internal fun preprocessCommandLineArguments(args: List, errors: ArgumentParseErrors): List = - args.flatMap { - if (it.isArgumentForArgfile) - File(it.argfilePath).expand(errors) - else - listOf(it) + args.flatMap { arg -> + if (arg.isArgfileArgument) { + File(arg.argfilePath).expand(errors) + } else if (arg.isDeprecatedArgfileArgument) { + errors.deprecatedArguments[EXPERIMENTAL_ARGFILE_ARGUMENT] = ARGFILE_ARGUMENT + + File(arg.deprecatedArgfilePath).expand(errors) + } else { + listOf(arg) + } } private fun File.expand(errors: ArgumentParseErrors): List { @@ -80,9 +86,13 @@ private fun Reader.nextChar(): Char? = read().takeUnless { it == -1 }?.toChar() private val String.argfilePath: String - get() = removePrefix("$EXPERIMENTAL_ARGFILE_ARGUMENT=") + get() = removePrefix(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("$EXPERIMENTAL_ARGFILE_ARGUMENT=") +private val String.isArgfileArgument: Boolean + get() = startsWith(ARGFILE_ARGUMENT) + +private val String.deprecatedArgfilePath: String + get() = removePrefix(EXPERIMENTAL_ARGFILE_ARGUMENT) + +private val String.isDeprecatedArgfileArgument: Boolean + get() = startsWith(EXPERIMENTAL_ARGFILE_ARGUMENT) diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java index e480256e1e7..ec421b57381 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/Usage.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.cli.common.arguments.Argument; import org.jetbrains.kotlin.cli.common.arguments.CommonToolArguments; import org.jetbrains.kotlin.cli.common.arguments.ParseCommandLineArgumentsKt; +import org.jetbrains.kotlin.cli.common.arguments.PreprocessCommandLineArgumentsKt; public class Usage { // The magic number 29 corresponds to the similar padding width in javac and scalac command line compilers @@ -33,19 +34,23 @@ public class Usage { @NotNull public static String render(@NotNull CLITool tool, @NotNull A arguments) { + boolean extraHelp = arguments.getExtraHelp(); StringBuilder sb = new StringBuilder(); appendln(sb, "Usage: " + tool.executableScriptFileName() + " "); - appendln(sb, "where " + (arguments.getExtraHelp() ? "advanced" : "possible") + " options include:"); + appendln(sb, "where " + (extraHelp ? "advanced" : "possible") + " options include:"); KClass kClass = JvmClassMappingKt.getKotlinClass(arguments.getClass()); for (KCallable callable : kClass.getMembers()) { if (!(callable instanceof KProperty1)) continue; - propertyUsage(sb, (KProperty1) callable, arguments.getExtraHelp()); + propertyUsage(sb, (KProperty1) callable, extraHelp); } - if (arguments.getExtraHelp()) { + if (extraHelp) { appendln(sb, ""); appendln(sb, "Advanced options are non-standard and may be changed or removed without any notice."); } + else { + renderArgfileUsage(sb); + } return sb.toString(); } @@ -84,6 +89,17 @@ public class Usage { appendln(sb, argument.description().replace("\n", "\n" + StringsKt.repeat(" ", OPTION_NAME_PADDING_WIDTH))); } + private static void renderArgfileUsage(@NotNull StringBuilder sb) { + int descriptionStart = sb.length() + OPTION_NAME_PADDING_WIDTH; + sb.append(" "); + sb.append(PreprocessCommandLineArgumentsKt.ARGFILE_ARGUMENT); + sb.append(""); + while (sb.length() < descriptionStart) { + sb.append(" "); + } + appendln(sb, "Expand compiler arguments from the given file, containing one argument or file path per line"); + } + private static void appendln(@NotNull StringBuilder sb, @NotNull String string) { sb.append(string); StringsKt.appendln(sb); diff --git a/compiler/testData/cli/js-dce/dceHelp.out b/compiler/testData/cli/js-dce/dceHelp.out index c4bec792ee1..966f9856b7e 100644 --- a/compiler/testData/cli/js-dce/dceHelp.out +++ b/compiler/testData/cli/js-dce/dceHelp.out @@ -10,4 +10,5 @@ where possible options include: -nowarn Generate no warnings -verbose Enable verbose logging output -version Display compiler version + @ Expand compiler arguments from the given file, containing one argument or file path per line OK diff --git a/compiler/testData/cli/js/jsHelp.out b/compiler/testData/cli/js/jsHelp.out index af510cfa755..94df7c00510 100644 --- a/compiler/testData/cli/js/jsHelp.out +++ b/compiler/testData/cli/js/jsHelp.out @@ -31,4 +31,5 @@ where possible options include: -nowarn Generate no warnings -verbose Enable verbose logging output -version Display compiler version + @ Expand compiler arguments from the given file, containing one argument or file path per line OK diff --git a/compiler/testData/cli/jvm/apiVersionLessThanLanguageUsingArgfile.args b/compiler/testData/cli/jvm/apiVersionLessThanLanguageUsingArgfile.args index ae9449ad7a5..8055905cd7f 100644 --- a/compiler/testData/cli/jvm/apiVersionLessThanLanguageUsingArgfile.args +++ b/compiler/testData/cli/jvm/apiVersionLessThanLanguageUsingArgfile.args @@ -1 +1 @@ --Xargfile=$TESTDATA_DIR$/apiVersionLessThanLanguage.argfile \ No newline at end of file +@$TESTDATA_DIR$/apiVersionLessThanLanguage.argfile diff --git a/compiler/testData/cli/jvm/argfileWithEscaping.args b/compiler/testData/cli/jvm/argfileWithEscaping.args index a3a729c19bd..793486ea2da 100644 --- a/compiler/testData/cli/jvm/argfileWithEscaping.args +++ b/compiler/testData/cli/jvm/argfileWithEscaping.args @@ -1 +1 @@ --Xargfile=$TESTDATA_DIR$/argfileWithEscaping.argfile \ No newline at end of file +@$TESTDATA_DIR$/argfileWithEscaping.argfile diff --git a/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args index 25c76a92763..b04d3a76b5e 100644 --- a/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args +++ b/compiler/testData/cli/jvm/argfileWithUnfinishedQuoteAndEscape.args @@ -1 +1 @@ --Xargfile=$TESTDATA_DIR$/argfileWithUnfinishedQuoteAndEscape.argfile +@$TESTDATA_DIR$/argfileWithUnfinishedQuoteAndEscape.argfile diff --git a/compiler/testData/cli/jvm/help.out b/compiler/testData/cli/jvm/help.out index 1c97f31e718..6e4f3eca8a2 100644 --- a/compiler/testData/cli/jvm/help.out +++ b/compiler/testData/cli/jvm/help.out @@ -29,4 +29,5 @@ where possible options include: -nowarn Generate no warnings -verbose Enable verbose logging output -version Display compiler version + @ Expand compiler arguments from the given file, containing one argument or file path per line OK diff --git a/compiler/testData/cli/jvm/mixingArgfilesAndUsualArgs.args b/compiler/testData/cli/jvm/mixingArgfilesAndUsualArgs.args index d69246c82dd..3feda1849fa 100644 --- a/compiler/testData/cli/jvm/mixingArgfilesAndUsualArgs.args +++ b/compiler/testData/cli/jvm/mixingArgfilesAndUsualArgs.args @@ -1,3 +1,3 @@ $TESTDATA_DIR$/apiVersion.kt -d --Xargfile=$TESTDATA_DIR$/mixingArgfilesAndUsualArgs.argfile \ No newline at end of file +@$TESTDATA_DIR$/mixingArgfilesAndUsualArgs.argfile diff --git a/compiler/testData/cli/jvm/nonexistingArgfile.args b/compiler/testData/cli/jvm/nonexistingArgfile.args index 8b0b8866e2d..5f732efa71c 100644 --- a/compiler/testData/cli/jvm/nonexistingArgfile.args +++ b/compiler/testData/cli/jvm/nonexistingArgfile.args @@ -1,4 +1,4 @@ $TESTDATA_DIR$/simple.kt -d $TEMP_DIR$ --Xargfile=$TESTDATA_DIR$/nonexisting.argfile \ No newline at end of file +@$TESTDATA_DIR$/nonexisting.argfile diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java b/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java index fcd6c81570e..ab5fc3e38b0 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/cli/AbstractCliTest.java @@ -45,10 +45,11 @@ import java.io.File; import java.util.ArrayList; import java.util.List; +import static org.jetbrains.kotlin.cli.common.arguments.PreprocessCommandLineArgumentsKt.ARGFILE_ARGUMENT; + public abstract class AbstractCliTest extends TestCaseWithTmpdir { private static final String TESTDATA_DIR = "$TESTDATA_DIR$"; - private static final String EXPERIMENTAL_ARGFILE_ARGUMENT_PREFIX = "-Xargfile="; private static final String BUILD_FILE_ARGUMENT_PREFIX = "-Xbuild-file="; public static Pair executeCompilerGrabOutput(@NotNull CLITool compiler, @NotNull List args) { @@ -206,10 +207,8 @@ public abstract class AbstractCliTest extends TestCaseWithTmpdir { return createTempFileWithPathsReplaced(argWithTestPathsReplaced, BUILD_FILE_ARGUMENT_PREFIX, ".xml", testDataDir, tempDir); } - if (arg.startsWith(EXPERIMENTAL_ARGFILE_ARGUMENT_PREFIX)) { - return createTempFileWithPathsReplaced( - argWithTestPathsReplaced, EXPERIMENTAL_ARGFILE_ARGUMENT_PREFIX, "", testDataDir, tempDir - ); + if (arg.startsWith(ARGFILE_ARGUMENT)) { + return createTempFileWithPathsReplaced(argWithTestPathsReplaced, ARGFILE_ARGUMENT, "", testDataDir, tempDir); } return argWithTestPathsReplaced;