aboutsummaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorGravatar Luis Fernando Pino Duque <lpino@google.com>2016-03-18 17:14:43 +0000
committerGravatar Damien Martin-Guillerez <dmarting@google.com>2016-03-21 09:34:19 +0000
commit51a491b89a9cd5f15c9a093a5693bc37e696e6e1 (patch)
tree11e7c7e08ae7926aede36c4a0b2b012cf7c62f08 /src
parentc3620ef1b846be72fdf27d00a764a10d05e5cd4e (diff)
Add a new field to options called defaultMultipleValue which enables setting default values for
flags whose allowMultiple is true. The behavior is the following: - If allowMultiple is false then behave as previously. - Otherwise for retrieving the default we now look at defaultMultipleValue instead of defaultValue and in the process it will apply the converter to each element. If no defaultMultipleValue is specified then the default value will be an empty list. -- MOS_MIGRATED_REVID=117558645
Diffstat (limited to 'src')
-rw-r--r--src/main/java/com/google/devtools/common/options/Option.java12
-rw-r--r--src/main/java/com/google/devtools/common/options/OptionsData.java28
-rw-r--r--src/main/java/com/google/devtools/common/options/OptionsParserImpl.java5
-rw-r--r--src/test/java/com/google/devtools/common/options/OptionsParserTest.java32
4 files changed, 67 insertions, 10 deletions
diff --git a/src/main/java/com/google/devtools/common/options/Option.java b/src/main/java/com/google/devtools/common/options/Option.java
index a62558c4e7..5cd6b73c2c 100644
--- a/src/main/java/com/google/devtools/common/options/Option.java
+++ b/src/main/java/com/google/devtools/common/options/Option.java
@@ -63,12 +63,18 @@ public @interface Option {
* "null" is only applicable when computing the default value; if specified
* on the command-line, this string will have its usual literal meaning.
*
- * <p>The default value for flags that set allowMultiple to true is always
- * the empty list and the value in the annotation is ignored.
+ * <p>The default value for flags that set allowMultiple to true should be set with
+ * {@link #defaultMultipleValue()}
*/
String defaultValue();
/**
+ * This method is an extension of {@link #defaultValue()} and it enables setting default values
+ * for flags whose allowMultiple is true. In that case {@link #defaultValue()} is ignored.
+ */
+ String[] defaultMultipleValue() default {};
+
+ /**
* A string describing the category of options that this belongs to. {@link
* OptionsParser#describeOptions} prints options of the same category grouped
* together.
@@ -143,7 +149,7 @@ public @interface Option {
* when parsed. For example, if foo is a wrapper option, then "--foo=--bar=baz"
* will be parsed as the flag "--bar=baz" (rather than --foo taking the value
* "--bar=baz"). A wrapper option should have the type {@link Void} (if it is something other
- * than Void, the parser will not assign a value to it). The
+ * than Void, the parser will not assign a value to it). The
* {@link Option#implicitRequirements()}, {@link Option#expansion()}, {@link Option#converter()}
* attributes will not be processed. Wrapper options are implicitly repeatable (i.e., as though
* {@link Option#allowMultiple()} is true regardless of its value in the annotation).
diff --git a/src/main/java/com/google/devtools/common/options/OptionsData.java b/src/main/java/com/google/devtools/common/options/OptionsData.java
index c5fc91e0c8..2683121062 100644
--- a/src/main/java/com/google/devtools/common/options/OptionsData.java
+++ b/src/main/java/com/google/devtools/common/options/OptionsData.java
@@ -18,7 +18,6 @@ import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
-
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
@@ -76,7 +75,7 @@ final class OptionsData {
* values.
*/
private final Map<Field, Boolean> allowMultiple;
-
+
private OptionsData(Map<Class<? extends OptionsBase>, Constructor<?>> optionsClasses,
Map<String, Field> nameToField,
Map<Character, Field> abbrevToField,
@@ -130,7 +129,7 @@ final class OptionsData {
public boolean getAllowMultiple(Field field) {
return allowMultiple.get(field);
}
-
+
private static List<Field> getAllAnnotatedFields(Class<? extends OptionsBase> optionsClass) {
List<Field> allFields = Lists.newArrayList();
for (Field field : optionsClass.getFields()) {
@@ -146,11 +145,26 @@ final class OptionsData {
private static Object retrieveDefaultFromAnnotation(Field optionField) {
Option annotation = optionField.getAnnotation(Option.class);
- // If an option can be specified multiple times, its default value is a new empty list.
+ // If an option can be specified multiple times then get the default value from the
+ // defaultMultipleValue and ignore defaultValue
if (annotation.allowMultiple()) {
- return Collections.emptyList();
+ // Create a list with each value in defaultMultipleValue converted
+ String[] defaultMultipleValueString =
+ OptionsParserImpl.getDefaultMultipleOptionString(optionField);
+ ImmutableList.Builder<Object> builder = new ImmutableList.Builder<>();
+ for (String element : defaultMultipleValueString) {
+ builder.add(convertDefaultValueFromAnnotation(element, optionField));
+ }
+ return builder.build();
}
- String defaultValueString = OptionsParserImpl.getDefaultOptionString(optionField);
+ // Otherwise convert the defaultValue
+ return convertDefaultValueFromAnnotation(
+ OptionsParserImpl.getDefaultOptionString(optionField),
+ optionField);
+ }
+
+ private static Object convertDefaultValueFromAnnotation(String defaultValueString,
+ Field optionField) {
try {
return OptionsParserImpl.isSpecialNullDefault(defaultValueString, optionField)
? null
@@ -276,7 +290,7 @@ final class OptionsData {
optionDefaultsBuilder.put(field, retrieveDefaultFromAnnotation(field));
convertersBuilder.put(field, OptionsParserImpl.findConverter(field));
-
+
allowMultipleBuilder.put(field, annotation.allowMultiple());
}
}
diff --git a/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java b/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java
index 96fb4963fc..6f9ca021dc 100644
--- a/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java
+++ b/src/main/java/com/google/devtools/common/options/OptionsParserImpl.java
@@ -774,6 +774,11 @@ class OptionsParserImpl {
return annotation.defaultValue();
}
+ static String[] getDefaultMultipleOptionString(Field optionField) {
+ Option annotation = optionField.getAnnotation(Option.class);
+ return annotation.defaultMultipleValue();
+ }
+
static boolean isBooleanField(Field field) {
return field.getType().equals(boolean.class)
|| field.getType().equals(TriState.class)
diff --git a/src/test/java/com/google/devtools/common/options/OptionsParserTest.java b/src/test/java/com/google/devtools/common/options/OptionsParserTest.java
index 0448471a2f..468139e056 100644
--- a/src/test/java/com/google/devtools/common/options/OptionsParserTest.java
+++ b/src/test/java/com/google/devtools/common/options/OptionsParserTest.java
@@ -96,6 +96,22 @@ public class OptionsParserTest {
public String boom;
}
+ /**
+ * Example with multiple default values
+ */
+ public static class ExampleMultiple extends OptionsBase {
+ @Option(name = "multiple",
+ defaultValue = "",
+ defaultMultipleValue = {"a", "b"},
+ allowMultiple = true)
+ public List<String> multiple;
+
+ @Option(name = "emptyMultiple",
+ defaultValue = "",
+ allowMultiple = true)
+ public List<String> emptyMultiple;
+ }
+
public static class StringConverter implements Converter<String> {
@Override
public String convert(String input) {
@@ -201,6 +217,22 @@ public class OptionsParserTest {
assertNull(boom.boom);
}
+ @Test
+ public void parseWithMultipleDefaultValues() throws OptionsParsingException {
+ OptionsParser parser = newOptionsParser(ExampleMultiple.class);
+ parser.parse();
+ ExampleMultiple multiple = parser.getOptions(ExampleMultiple.class);
+ assertThat(multiple.multiple).containsExactly("a", "b");
+ }
+
+ @Test
+ public void parseWithEmptyMultipleDefaultValues() throws OptionsParsingException {
+ OptionsParser parser = newOptionsParser(ExampleMultiple.class);
+ parser.parse();
+ ExampleMultiple multiple = parser.getOptions(ExampleMultiple.class);
+ assertThat(multiple.emptyMultiple).isEmpty();
+ }
+
public static class CategoryTest extends OptionsBase {
@Option(name = "swiss_bank_account_number",
category = "undocumented", // Not printed in usage messages!