From ff846e787f43608a1612dc9d0da84441ce1d518d Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 6 Apr 2017 16:15:28 +0300 Subject: [PATCH] Report warning for non-boolean CLI argument passed multiple times Only if its values are different, see the test --- .../arguments/CommonCompilerArguments.java | 6 ++++ .../arguments/parseCommandLineArguments.kt | 7 ++++ .../kotlin/cli/common/CLICompiler.java | 8 +++-- .../cli/jvm/argumentPassedMultipleTimes.args | 16 +++++++++ .../cli/jvm/argumentPassedMultipleTimes.out | 2 ++ .../coroutinesEnableWarnAndErrorClash.args | 4 --- .../jvm/coroutinesEnableWarnAndErrorClash.out | 2 -- ...ash.args => coroutinesErrorAndEnable.args} | 4 ++- .../cli/jvm/coroutinesErrorAndEnable.out | 2 ++ .../cli/jvm/coroutinesErrorAndEnableClash.out | 2 -- ...tinesWarninig.args => coroutinesWarn.args} | 0 ...outinesWarninig.out => coroutinesWarn.out} | 0 .../cli/jvm/coroutinesWarnAndEnableClash.args | 3 -- .../cli/jvm/coroutinesWarnAndEnableClash.out | 2 -- .../cli/jvm/coroutinesWarnAndErrorClash.args | 3 -- .../cli/jvm/coroutinesWarnAndErrorClash.out | 2 -- .../kotlin/cli/CliTestGenerated.java | 36 +++++++------------ 17 files changed, 54 insertions(+), 45 deletions(-) create mode 100644 compiler/testData/cli/jvm/argumentPassedMultipleTimes.args create mode 100644 compiler/testData/cli/jvm/argumentPassedMultipleTimes.out delete mode 100644 compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.args delete mode 100644 compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.out rename compiler/testData/cli/jvm/{coroutinesErrorAndEnableClash.args => coroutinesErrorAndEnable.args} (56%) create mode 100644 compiler/testData/cli/jvm/coroutinesErrorAndEnable.out delete mode 100644 compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.out rename compiler/testData/cli/jvm/{coroutinesWarninig.args => coroutinesWarn.args} (100%) rename compiler/testData/cli/jvm/{coroutinesWarninig.out => coroutinesWarn.out} (100%) delete mode 100644 compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.args delete mode 100644 compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.out delete mode 100644 compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.args delete mode 100644 compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.out diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java index 0c3564c435f..9789918161a 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/CommonCompilerArguments.java @@ -20,7 +20,9 @@ import com.intellij.util.SmartList; import org.jetbrains.annotations.NotNull; import java.io.Serializable; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; public abstract class CommonCompilerArguments implements Serializable { public static final long serialVersionUID = 0L; @@ -105,6 +107,10 @@ public abstract class CommonCompilerArguments implements Serializable { // Names of extra (-X...) arguments which have been passed in an obsolete form ("-Xaaa bbb", instead of "-Xaaa=bbb") public List extraArgumentsPassedInObsoleteForm = new SmartList<>(); + // Non-boolean arguments which have been passed multiple times, possibly with different values. + // The key in the map is the name of the argument, the value is the last passed value. + public Map duplicateArguments = new LinkedHashMap<>(); + @NotNull public static CommonCompilerArguments createDefaultInstance() { return new DummyImpl(); diff --git a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt index a08fd04816f..9b7c57c7ac3 100644 --- a/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt +++ b/compiler/cli/cli-common/src/org/jetbrains/kotlin/cli/common/arguments/parseCommandLineArguments.kt @@ -30,6 +30,7 @@ val Argument.isAdvanced: Boolean private val ADVANCED_ARGUMENT_PREFIX = "-X" +// Parses arguments in the passed [result] object, or throws an [IllegalArgumentException] with the message to be displayed to the user fun parseCommandLineArguments(args: Array, result: A) { data class ArgumentField(val field: Field, val argument: Argument) @@ -38,6 +39,8 @@ fun parseCommandLineArguments(args: Array, if (argument != null) ArgumentField(field, argument) else null } + val visitedArgs = mutableSetOf() + var i = 0 while (i < args.size) { val arg = args[i++] @@ -74,6 +77,10 @@ fun parseCommandLineArguments(args: Array, } } + if (!field.type.isArray && !visitedArgs.add(argument.value) && value is String && field.get(result) != value) { + result.duplicateArguments.put(argument.value, value) + } + updateField(field, result, value) } } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java index 60f7bea5fdc..4adedc24355 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/common/CLICompiler.java @@ -136,7 +136,7 @@ public abstract class CLICompiler { messageCollector = new FilteringMessageCollector(messageCollector, Predicate.isEqual(WARNING)); } - reportUnknownAndObsoleteExtraFlags(messageCollector, arguments); + reportArgumentParseProblems(messageCollector, arguments); GroupingMessageCollector groupingCollector = new GroupingMessageCollector(messageCollector); @@ -311,7 +311,7 @@ public abstract class CLICompiler { @NotNull CompilerConfiguration configuration, @NotNull A arguments, @NotNull Services services ); - private void reportUnknownAndObsoleteExtraFlags(@NotNull MessageCollector collector, @NotNull A arguments) { + private void reportArgumentParseProblems(@NotNull MessageCollector collector, @NotNull A arguments) { for (String flag : arguments.unknownExtraFlags) { collector.report(STRONG_WARNING, "Flag is not supported by this version of the compiler: " + flag, null); } @@ -319,6 +319,10 @@ public abstract class CLICompiler { collector.report(STRONG_WARNING, "Advanced option value is passed in an obsolete form. Please use the '=' character " + "to specify the value: " + argument + "=...", null); } + for (Map.Entry argument : arguments.duplicateArguments.entrySet()) { + collector.report(STRONG_WARNING, "Argument " + argument.getKey() + " is passed multiple times. " + + "Only the last value will be used: " + argument.getValue(), null); + } } @NotNull diff --git a/compiler/testData/cli/jvm/argumentPassedMultipleTimes.args b/compiler/testData/cli/jvm/argumentPassedMultipleTimes.args new file mode 100644 index 00000000000..02ed5a310af --- /dev/null +++ b/compiler/testData/cli/jvm/argumentPassedMultipleTimes.args @@ -0,0 +1,16 @@ +$TESTDATA_DIR$/simple.kt +-cp +$TESTDATA_DIR$ +-cp +$TESTDATA_DIR$ +-java-parameters +-java-parameters +-Xno-inline +-d +$TEMP_DIR$ +-java-parameters +-Xno-inline +-module-name +aaa +-module-name +bbb diff --git a/compiler/testData/cli/jvm/argumentPassedMultipleTimes.out b/compiler/testData/cli/jvm/argumentPassedMultipleTimes.out new file mode 100644 index 00000000000..ad1d636c225 --- /dev/null +++ b/compiler/testData/cli/jvm/argumentPassedMultipleTimes.out @@ -0,0 +1,2 @@ +warning: argument -module-name is passed multiple times. Only the last value will be used: bbb +OK diff --git a/compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.args b/compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.args deleted file mode 100644 index daad4373a5e..00000000000 --- a/compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.args +++ /dev/null @@ -1,4 +0,0 @@ -$TESTDATA_DIR$/simple.kt --Xcoroutines=enable --Xcoroutines=warn --Xcoroutines=error \ No newline at end of file diff --git a/compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.out b/compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.out deleted file mode 100644 index b4ff1d1bb1a..00000000000 --- a/compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.out +++ /dev/null @@ -1,2 +0,0 @@ -error: the -Xcoroutines can only have one value -COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.args b/compiler/testData/cli/jvm/coroutinesErrorAndEnable.args similarity index 56% rename from compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.args rename to compiler/testData/cli/jvm/coroutinesErrorAndEnable.args index a6bdf02e284..fe47366cf5d 100644 --- a/compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.args +++ b/compiler/testData/cli/jvm/coroutinesErrorAndEnable.args @@ -1,3 +1,5 @@ $TESTDATA_DIR$/simple.kt -Xcoroutines=error --Xcoroutines=enable \ No newline at end of file +-Xcoroutines=enable +-d +$TEMP_DIR$ diff --git a/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out b/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out new file mode 100644 index 00000000000..ac6ae4be5aa --- /dev/null +++ b/compiler/testData/cli/jvm/coroutinesErrorAndEnable.out @@ -0,0 +1,2 @@ +warning: argument -Xcoroutines is passed multiple times. Only the last value will be used: enable +OK \ No newline at end of file diff --git a/compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.out b/compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.out deleted file mode 100644 index b4ff1d1bb1a..00000000000 --- a/compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.out +++ /dev/null @@ -1,2 +0,0 @@ -error: the -Xcoroutines can only have one value -COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/coroutinesWarninig.args b/compiler/testData/cli/jvm/coroutinesWarn.args similarity index 100% rename from compiler/testData/cli/jvm/coroutinesWarninig.args rename to compiler/testData/cli/jvm/coroutinesWarn.args diff --git a/compiler/testData/cli/jvm/coroutinesWarninig.out b/compiler/testData/cli/jvm/coroutinesWarn.out similarity index 100% rename from compiler/testData/cli/jvm/coroutinesWarninig.out rename to compiler/testData/cli/jvm/coroutinesWarn.out diff --git a/compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.args b/compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.args deleted file mode 100644 index 5d63597a8d2..00000000000 --- a/compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.args +++ /dev/null @@ -1,3 +0,0 @@ -$TESTDATA_DIR$/simple.kt --Xcoroutines=warn --Xcoroutines=enable \ No newline at end of file diff --git a/compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.out b/compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.out deleted file mode 100644 index b4ff1d1bb1a..00000000000 --- a/compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.out +++ /dev/null @@ -1,2 +0,0 @@ -error: the -Xcoroutines can only have one value -COMPILATION_ERROR diff --git a/compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.args b/compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.args deleted file mode 100644 index 989221e562b..00000000000 --- a/compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.args +++ /dev/null @@ -1,3 +0,0 @@ -$TESTDATA_DIR$/simple.kt --Xcoroutines=warn --Xcoroutines=error \ No newline at end of file diff --git a/compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.out b/compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.out deleted file mode 100644 index e949a41d8b3..00000000000 --- a/compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.out +++ /dev/null @@ -1,2 +0,0 @@ -error: the -Xcoroutines can only have one value -COMPILATION_ERROR \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java index 5b98f0d4d09..e45f0c29816 100644 --- a/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java +++ b/compiler/tests/org/jetbrains/kotlin/cli/CliTestGenerated.java @@ -74,6 +74,12 @@ public class CliTestGenerated extends AbstractCliTest { doJvmTest(fileName); } + @TestMetadata("argumentPassedMultipleTimes.args") + public void testArgumentPassedMultipleTimes() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/argumentPassedMultipleTimes.args"); + doJvmTest(fileName); + } + @TestMetadata("classAndFileClassClash.args") public void testClassAndFileClassClash() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/classAndFileClassClash.args"); @@ -128,39 +134,21 @@ public class CliTestGenerated extends AbstractCliTest { doJvmTest(fileName); } - @TestMetadata("coroutinesEnableWarnAndErrorClash.args") - public void testCoroutinesEnableWarnAndErrorClash() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesEnableWarnAndErrorClash.args"); - doJvmTest(fileName); - } - @TestMetadata("coroutinesError.args") public void testCoroutinesError() throws Exception { String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesError.args"); doJvmTest(fileName); } - @TestMetadata("coroutinesErrorAndEnableClash.args") - public void testCoroutinesErrorAndEnableClash() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesErrorAndEnableClash.args"); + @TestMetadata("coroutinesErrorAndEnable.args") + public void testCoroutinesErrorAndEnable() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesErrorAndEnable.args"); doJvmTest(fileName); } - @TestMetadata("coroutinesWarnAndEnableClash.args") - public void testCoroutinesWarnAndEnableClash() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesWarnAndEnableClash.args"); - doJvmTest(fileName); - } - - @TestMetadata("coroutinesWarnAndErrorClash.args") - public void testCoroutinesWarnAndErrorClash() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesWarnAndErrorClash.args"); - doJvmTest(fileName); - } - - @TestMetadata("coroutinesWarninig.args") - public void testCoroutinesWarninig() throws Exception { - String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesWarninig.args"); + @TestMetadata("coroutinesWarn.args") + public void testCoroutinesWarn() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/cli/jvm/coroutinesWarn.args"); doJvmTest(fileName); }