#500 Add picocli annotation processor

* add separate module picocli-annotation-processing-tests for testing (com.google.testing.compile:compile-testing requires Java 8)
* (API) add ITypeInfo that encapsulated type information available at both runtime and compile time
* add RuntimeTypeInfo implementation used at runtime (reflection)
* (API) add IAnnotatedElement as public API for method and fields annotated with any picocli annotation
* internal class TypedMember now implements IAnnotatedElement
* (API) CommandSpec.resourceBundleBaseName() getter and setter
* (API) Messages.resourceBundleBaseName() getter
* (API) ArgSpec.userObject() getter
* (API) made MethodParam public
* IGetter/ISetter implementations now have informative toString() methods
* removed internal class ArgsReflection
This commit is contained in:
Remko Popma
2019-01-31 07:50:15 +09:00
parent b644a65726
commit e8e1b44ae7
62 changed files with 7785 additions and 356 deletions

View File

@@ -1,4 +1,5 @@
asciidoctorGradlePluginVersion = 1.5.3
compileTestingVersion = 0.15
gradleBintrayPluginVersion = 1.+
groovyVersion = 2.4.10
hamcrestCoreVersion = 1.3
@@ -14,7 +15,7 @@ junitVersion = 4.12
projectPreviousReleaseVersion = 3\\.9\\.2
# projectPreviousVersionRegex may be a SNAPSHOT
projectPreviousVersionRegex = 3\\.9\\.2
projectVersion = 3.9.3-SNAPSHOT
projectVersion = 4.0.0-alpha-1-SNAPSHOT
releaseDate = 2019-01-20
releaseDatePreviousRegex = 2019\\-01\\-20

59
logging.properties Normal file
View File

@@ -0,0 +1,59 @@
############################################################
# Default Logging Configuration File
#
# You can use a different file by specifying a filename
# with the java.util.logging.config.file system property.
# For example java -Djava.util.logging.config.file=myfile
############################################################
############################################################
# Global properties
############################################################
# "handlers" specifies a comma separated list of log Handler
# classes. These handlers will be installed during VM startup.
# Note that these classes must be on the system classpath.
# By default we only configure a ConsoleHandler, which will only
# show messages at the INFO and above levels.
handlers= java.util.logging.ConsoleHandler
# To also add the FileHandler, use the following line instead.
#handlers= java.util.logging.FileHandler, java.util.logging.ConsoleHandler
# Default global logging level.
# This specifies which kinds of events are logged across
# all loggers. For any given facility this global level
# can be overriden by a facility specific level
# Note that the ConsoleHandler also has a separate level
# setting to limit messages printed to the console.
.level= FINE
############################################################
# Handler specific properties.
# Describes specific configuration info for Handlers.
############################################################
# default file output is in user's home directory.
java.util.logging.FileHandler.pattern = %h/java%u.log
java.util.logging.FileHandler.limit = 50000
java.util.logging.FileHandler.count = 1
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter
# Limit the message that are printed on the console to INFO and above.
java.util.logging.ConsoleHandler.level = FINE
java.util.logging.ConsoleHandler.formatter = java.util.logging.SimpleFormatter
# Example to customize the SimpleFormatter output format
# to print one-line log message like this:
# <level>: <log message> [<date/time>]
#
# java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
############################################################
# Facility specific properties.
# Provides extra control for each logger.
############################################################
# For example, set the com.xyz.foo logger to only log SEVERE
# messages:
com.xyz.foo.level = SEVERE

View File

@@ -0,0 +1,28 @@
plugins {
id 'java'
}
group 'info.picocli'
description 'Picocli Annotation Processing Tests - Tests Annotation Processors for picocli Annotations.'
version "$projectVersion"
sourceCompatibility = 1.8
targetCompatibility = 1.8
dependencies {
compile rootProject
compile project(':picocli-codegen')
testCompile "junit:junit:$junitVersion",
"com.google.testing.compile:compile-testing:$compileTestingVersion",
files(org.gradle.internal.jvm.Jvm.current().getToolsJar()) // workaround https://github.com/google/compile-testing/issues/102 (and #28)
}
jar {
manifest {
attributes 'Specification-Title': 'Picocli Annotation Processing Tests',
'Specification-Vendor' : 'Remko Popma',
'Specification-Version' : version,
'Implementation-Title' : 'Picocli Annotation Processing Tests',
'Implementation-Vendor' : 'Remko Popma',
'Implementation-Version': version,
'Automatic-Module-Name' : 'info.picocli.annotation.processing.tests'
}
}

View File

@@ -0,0 +1,36 @@
package picocli.annotation.processing.tests;
import picocli.CommandLine.Model.CommandSpec;
import picocli.codegen.annotation.processing.AbstractCommandSpecProcessor;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class CommandSpec2YamlProcessor extends AbstractCommandSpecProcessor {
public List<String> strings = new ArrayList<String>();
public Map<Element, CommandSpec> commands;
@Override
protected boolean handleCommands(Map<Element, CommandSpec> commands,
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
System.out.println(commands);
this.commands = commands;
CommandSpecYamlPrinter printer = new CommandSpecYamlPrinter();
for (Map.Entry<Element, CommandSpec> entry : commands.entrySet()) {
StringWriter sw = new StringWriter();
printer.print(entry.getValue(), new PrintWriter(sw));
strings.add(sw.toString());
}
return false;
}
}

View File

@@ -0,0 +1,234 @@
package picocli.annotation.processing.tests;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Model.ArgSpec;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Model.OptionSpec;
import picocli.CommandLine.Model.ParserSpec;
import picocli.CommandLine.Model.PositionalParamSpec;
import picocli.CommandLine.Model.UnmatchedArgsBinding;
import picocli.CommandLine.Model.UsageMessageSpec;
import picocli.CommandLine.Parameters;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.ResourceBundle;
/**
* Dumps a {@code CommandSpec} in YAML format.
*/
public class CommandSpecYamlPrinter {
public static void main(String... args) {
CommandLine.run(new App(), args);
}
static void print(Object userObject) {
print(CommandSpec.forAnnotatedObject(userObject));
}
static void print(CommandSpec spec) {
StringWriter sw = new StringWriter();
new CommandSpecYamlPrinter().print(spec, new PrintWriter(sw));
System.out.println(sw);
}
public void print(CommandSpec spec, PrintWriter pw) {
pw.println("---");
printCommandSpec(spec, "CommandSpec:", pw, " ", " ");
}
private void printCommandSpec(CommandSpec spec, String label, PrintWriter pw,
String initialIndent, String indent) {
pw.printf("%s%n", label);
pw.printf("%sname: '%s'%n", initialIndent, spec.name());
pw.printf("%saliases: %s%n", indent, Arrays.toString(spec.aliases()));
pw.printf("%suserObject: %s%n", indent, spec.userObject());
pw.printf("%shelpCommand: %s%n", indent, spec.helpCommand());
pw.printf("%sdefaultValueProvider: %s%n", indent, spec.defaultValueProvider());
pw.printf("%sversionProvider: %s%n", indent, spec.versionProvider());
pw.printf("%sversion: %s%n", indent, Arrays.toString(spec.version()));
List<OptionSpec> options = new ArrayList<OptionSpec>(spec.options());
Collections.sort(options, new Comparator<OptionSpec>() {
public int compare(OptionSpec o1, OptionSpec o2) {
return o1.shortestName().compareTo(o2.shortestName());
}
});
printOptionList(options, pw, indent);
printPositionalList(spec.positionalParameters(), pw, indent);
printUnmatchedArgsBindingList(spec.unmatchedArgsBindings(), pw, indent);
printMixinList(spec.mixins(), pw, indent);
printUsageMessage(spec.usageMessage(), pw, indent);
printParser(spec.parser(), pw, indent);
printResourceBundle(spec.resourceBundle(), pw, indent);
printSubcommandList(spec.subcommands(), pw, indent);
}
private void printResourceBundle(ResourceBundle resourceBundle, PrintWriter pw, String indent) {
if (resourceBundle == null) {
return;
}
pw.printf("%sResourceBundle:%n", indent);
indent += " ";
for (Enumeration<String> keys = resourceBundle.getKeys(); keys.hasMoreElements();) {
String key = keys.nextElement();
pw.printf("%s%s: '%s'%n", indent, key, resourceBundle.getString(key));
}
}
private void printParser(ParserSpec parser, PrintWriter pw, String indent) {
pw.printf("%sParserSpec:%n", indent);
indent += " ";
pw.printf("%sseparator: '%s'%n", indent, parser.separator());
pw.printf("%sendOfOptionsDelimiter: '%s'%n", indent, parser.endOfOptionsDelimiter());
pw.printf("%sexpandAtFiles: %s%n", indent, parser.expandAtFiles());
pw.printf("%satFileCommentChar: '%s'%n", indent, parser.atFileCommentChar());
pw.printf("%soverwrittenOptionsAllowed: %s%n", indent, parser.overwrittenOptionsAllowed());
pw.printf("%sunmatchedArgumentsAllowed: %s%n", indent, parser.unmatchedArgumentsAllowed());
pw.printf("%sunmatchedOptionsArePositionalParams: %s%n", indent, parser.unmatchedOptionsArePositionalParams());
pw.printf("%sstopAtUnmatched: %s%n", indent, parser.stopAtUnmatched());
pw.printf("%sstopAtPositional: %s%n", indent, parser.stopAtPositional());
pw.printf("%sposixClusteredShortOptionsAllowed: %s%n", indent, parser.posixClusteredShortOptionsAllowed());
pw.printf("%saritySatisfiedByAttachedOptionParam: %s%n", indent, parser.aritySatisfiedByAttachedOptionParam());
pw.printf("%scaseInsensitiveEnumValuesAllowed: %s%n", indent, parser.caseInsensitiveEnumValuesAllowed());
pw.printf("%scollectErrors: %s%n", indent, parser.collectErrors());
pw.printf("%slimitSplit: %s%n", indent, parser.limitSplit());
pw.printf("%stoggleBooleanFlags: %s%n", indent, parser.toggleBooleanFlags());
}
private void printUsageMessage(UsageMessageSpec usageMessage, PrintWriter pw, String indent) {
pw.printf("%sUsageMessageSpec:%n", indent);
indent += " ";
pw.printf("%swidth: %s%n", indent, usageMessage.width());
pw.printf("%sabbreviateSynopsis: %s%n", indent, usageMessage.abbreviateSynopsis());
pw.printf("%shidden: %s%n", indent, usageMessage.hidden());
pw.printf("%sshowDefaultValues: %s%n", indent, usageMessage.showDefaultValues());
pw.printf("%ssortOptions: %s%n", indent, usageMessage.sortOptions());
pw.printf("%srequiredOptionMarker: '%s'%n", indent, usageMessage.requiredOptionMarker());
pw.printf("%sheaderHeading: '%s'%n", indent, usageMessage.headerHeading());
pw.printf("%sheader: %s%n", indent, Arrays.toString(usageMessage.header()));
pw.printf("%ssynopsisHeading: '%s'%n", indent, usageMessage.synopsisHeading());
pw.printf("%scustomSynopsis: %s%n", indent, Arrays.toString(usageMessage.customSynopsis()));
pw.printf("%sdescriptionHeading: '%s'%n", indent, usageMessage.descriptionHeading());
pw.printf("%sdescription: %s%n", indent, Arrays.toString(usageMessage.description()));
pw.printf("%sparameterListHeading: '%s'%n", indent, usageMessage.parameterListHeading());
pw.printf("%soptionListHeading: '%s'%n", indent, usageMessage.optionListHeading());
pw.printf("%scommandListHeading: '%s'%n", indent, usageMessage.commandListHeading());
pw.printf("%sfooterHeading: '%s'%n", indent, usageMessage.footerHeading());
pw.printf("%sfooter: %s%n", indent, Arrays.toString(usageMessage.footer()));
}
private void printUnmatchedArgsBindingList(List<UnmatchedArgsBinding> unmatchedArgsBindings, PrintWriter pw, String indent) {
pw.printf("%sUnmatchedArgsBindings:", indent);
pw.println(unmatchedArgsBindings.isEmpty() ? " []" : "");
for (UnmatchedArgsBinding unmatched : unmatchedArgsBindings) {
pw.printf("%sgetter: %s%n", indent + "- ", unmatched.getter());
pw.printf("%ssetter: %s%n", indent + " ", unmatched.setter());
}
}
private void printMixinList(Map<String, CommandSpec> mixins, PrintWriter pw, String indent) {
pw.printf("%sMixins:", indent);
pw.println(mixins.isEmpty() ? " []" : "");
for (Map.Entry<String, CommandSpec> entry : mixins.entrySet()) {
printCommandSpec(entry.getValue(), indent + "# " + entry.getKey(), pw, indent + "- ", indent + " ");
}
}
private void printSubcommandList(Map<String, CommandLine> subcommands, PrintWriter pw, String indent) {
pw.printf("%sSubcommands:", indent);
pw.println(subcommands.isEmpty() ? " []" : "");
for (Map.Entry<String, CommandLine> entry : subcommands.entrySet()) {
printCommandSpec(entry.getValue().getCommandSpec(),
indent + "# " + entry.getKey(), pw, indent + "- ", indent + " ");
}
}
private void printOptionList(List<OptionSpec> options, PrintWriter pw, String indent) {
pw.printf("%sOptions:", indent);
pw.println(options.isEmpty() ? " []" : "");
for (OptionSpec option : options) {
printOption(option, pw, indent);
}
}
private void printOption(OptionSpec option, PrintWriter pw, String indent) {
pw.printf("%snames: %s%n", indent + "- ", Arrays.toString(option.names()));
indent += " ";
pw.printf("%susageHelp: %s%n", indent, option.usageHelp());
pw.printf("%sversionHelp: %s%n", indent, option.versionHelp());
printArg(option, pw, indent);
}
private void printPositionalList(List<PositionalParamSpec> positionals, PrintWriter pw, String indent) {
pw.printf("%sPositionalParams:", indent);
pw.println(positionals.isEmpty() ? " []" : "");
for (PositionalParamSpec positional : positionals) {
printPositional(positional, pw, indent);
}
}
private void printPositional(PositionalParamSpec positional, PrintWriter pw, String indent) {
pw.printf("%sindex: %s%n", indent + "- ", positional.index());
indent += " ";
printArg(positional, pw, indent);
}
private void printArg(ArgSpec arg, PrintWriter pw, String indent) {
pw.printf("%sdescription: %s%n", indent, Arrays.toString(arg.description()));
pw.printf("%sdescriptionKey: '%s'%n", indent, arg.descriptionKey());
pw.printf("%stypeInfo: %s%n", indent, arg.typeInfo());
pw.printf("%sarity: %s%n", indent, arg.arity());
pw.printf("%ssplitRegex: '%s'%n", indent, arg.splitRegex());
pw.printf("%sinteractive: %s%n", indent, arg.interactive());
pw.printf("%srequired: %s%n", indent, arg.required());
pw.printf("%shidden: %s%n", indent, arg.hidden());
pw.printf("%shideParamSyntax: %s%n", indent, arg.hideParamSyntax());
pw.printf("%sdefaultValue: '%s'%n", indent, arg.defaultValue());
pw.printf("%sshowDefaultValue: %s%n", indent, arg.showDefaultValue());
pw.printf("%shasInitialValue: %s%n", indent, arg.hasInitialValue());
pw.printf("%sinitialValue: '%s'%n", indent, arg.initialValue());
pw.printf("%sparamLabel: '%s'%n", indent, arg.paramLabel());
pw.printf("%sconverters: %s%n", indent, Arrays.toString(arg.converters()));
pw.printf("%scompletionCandidates: %s%n", indent, iter(arg.completionCandidates()));
pw.printf("%sgetter: %s%n", indent, arg.getter());
pw.printf("%ssetter: %s%n", indent, arg.setter());
}
private String iter(Iterable<String> iterable) {
if (iterable == null) { return "null"; }
StringBuilder sb = new StringBuilder();
sb.append("[");
String sep = "";
for (String str : iterable) {
sb.append(sep).append(str);
sep = ", ";
}
return sb.append("]").toString();
}
@Command(name = "CommandSpecYamlPrinter", mixinStandardHelpOptions = true,
description = "Prints details of a CommandSpec")
private static class App implements Runnable {
@Parameters(arity = "1..*")
Class<?>[] classes = new Class[0];
// @Override (requires Java 6)
public void run() {
for (Class<?> cls : classes) {
StringWriter sw = new StringWriter();
new CommandSpecYamlPrinter().print(CommandSpec.forAnnotatedObject(cls), new PrintWriter(sw));
System.out.println(sw);
}
}
}
}

View File

@@ -0,0 +1 @@
picocli.annotation.processing.tests.CommandSpec2YamlProcessor

View File

@@ -0,0 +1,269 @@
package picocli.annotation.processing.tests;
import com.google.common.collect.ImmutableList;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;
import org.hamcrest.MatcherAssert;
import org.junit.Assert;
import org.junit.Test;
import javax.tools.Diagnostic;
import javax.tools.JavaFileObject;
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Scanner;
import java.util.Set;
import java.util.TreeSet;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static com.google.testing.compile.Compiler.javac;
import static org.hamcrest.CoreMatchers.containsString;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.junit.Assert.*;
import static picocli.codegen.util.Resources.slurp;
import static picocli.codegen.util.Resources.slurpAll;
public class AbstractCommandSpecProcessorTest {
@Test
public void testCommandWithMixin() {
Compilation compilation = compareCommandDump(slurp("/picocli/examples/mixin/CommandWithMixin.yaml"),
JavaFileObjects.forResource("picocli/examples/mixin/CommandWithMixin.java"),
JavaFileObjects.forResource("picocli/examples/mixin/CommonOption.java"));
assertOnlySourceVersionWarning(compilation);
}
@Test
public void testSubcommands() {
Compilation compilation = compareCommandDump(slurp("/picocli/examples/subcommands/FileUtils.yaml"),
JavaFileObjects.forResource("picocli/examples/subcommands/ParentCommandDemo.java"));
assertOnlySourceVersionWarning(compilation);
}
@Test
public void testSetterMethodOnClass() {
List<String> expected = slurpAll("/picocli/examples/annotatedmethods/CPrimitives.yaml",
"/picocli/examples/annotatedmethods/CPrimitivesWithDefault.yaml",
"/picocli/examples/annotatedmethods/CObjectsWithDefaults.yaml",
"/picocli/examples/annotatedmethods/CObjects.yaml"
);
Compilation compilation = compareCommandDump(expected,
JavaFileObjects.forResource(
"picocli/examples/annotatedmethods/AnnotatedClassMethodOptions.java"));
assertOnlySourceVersionWarning(compilation);
}
@Test
public void testGetterMethodOnInterface() {
List<String> expected = slurpAll("/picocli/examples/annotatedmethods/IFPrimitives.yaml",
"/picocli/examples/annotatedmethods/IFPrimitivesWithDefault.yaml",
"/picocli/examples/annotatedmethods/IFObjects.yaml",
"/picocli/examples/annotatedmethods/IFObjectsWithDefault.yaml");
Compilation compilation = compareCommandDump(expected,
JavaFileObjects.forResource(
"picocli/examples/annotatedmethods/AnnotatedInterfaceMethodOptions.java"));
assertOnlySourceVersionWarning(compilation);
}
@Test
public void testInvalidAnnotationsOnInterface() {
CommandSpec2YamlProcessor processor = new CommandSpec2YamlProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(JavaFileObjects.forResource(
"picocli/examples/annotatedmethods/InvalidAnnotatedInterfaceMethodOptions.java"));
assertThat(compilation).failed();
ImmutableList<Diagnostic<? extends JavaFileObject>> errors = compilation.errors();
assertEquals("expected error count", 3, errors.size());
for (Diagnostic<? extends JavaFileObject> diag : errors) {
MatcherAssert.assertThat(diag.getMessage(Locale.ENGLISH),
containsString("Invalid picocli annotation on interface field"));
}
//assertThat(compilation).hadErrorContaining("Invalid picocli annotation on interface field");
}
@Test
public void testInvalidAnnotationCombinations() {
CommandSpec2YamlProcessor processor = new CommandSpec2YamlProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(JavaFileObjects.forResource(
"picocli/examples/validation/Invalid.java"));
assertThat(compilation).failed();
Set<String> expected = new TreeSet<>(Arrays.asList(
"Subcommand is missing @Command annotation with a name attribute",
"Subcommand @Command annotation should have a name attribute",
"@Mixin must have a declared type, not int",
"invalidOptionAndMixin cannot have both @picocli.CommandLine.Mixin and @picocli.CommandLine.Option annotations",
"invalidParametersAndMixin cannot have both @picocli.CommandLine.Mixin and @picocli.CommandLine.Parameters annotations",
"invalidUnmatchedAndMixin cannot have both @picocli.CommandLine.Mixin and @picocli.CommandLine.Unmatched annotations",
"invalidSpecAndMixin cannot have both @picocli.CommandLine.Mixin and @picocli.CommandLine.Spec annotations",
"invalidOptionAndUnmatched cannot have both @picocli.CommandLine.Unmatched and @picocli.CommandLine.Option annotations",
"invalidParametersAndUnmatched cannot have both @picocli.CommandLine.Unmatched and @picocli.CommandLine.Parameters annotations",
"invalidOptionAndSpec cannot have both @picocli.CommandLine.Spec and @picocli.CommandLine.Option annotations",
"invalidParametersAndSpec cannot have both @picocli.CommandLine.Spec and @picocli.CommandLine.Parameters annotations",
"invalidUnmatchedAndSpec cannot have both @picocli.CommandLine.Spec and @picocli.CommandLine.Unmatched annotations",
"invalidOptionAndParameters cannot have both @picocli.CommandLine.Option and @picocli.CommandLine.Parameters annotations"
));
ImmutableList<Diagnostic<? extends JavaFileObject>> errors = compilation.errors();
for (Diagnostic<? extends JavaFileObject> diag : errors) {
assertTrue("Unexpected error: " + diag.getMessage(Locale.ENGLISH),
expected.remove(diag.getMessage(Locale.ENGLISH)));
}
assertTrue("Expected errors: " + expected, expected.isEmpty());
}
@Test
public void testCommandWithBundle() {
Compilation compilation = compareCommandDump(slurp("/picocli/examples/messages/CommandWithBundle.yaml"),
JavaFileObjects.forResource("picocli/examples/messages/CommandWithBundle.java"));
assertOnlySourceVersionWarning(compilation);
}
private Compilation compareCommandDump(String expected, JavaFileObject ... sourceFiles) {
return compareCommandDump(Arrays.asList(expected), sourceFiles);
}
private Compilation compareCommandDump(List<String> expected, JavaFileObject ... sourceFiles) {
CommandSpec2YamlProcessor processor = new CommandSpec2YamlProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(sourceFiles);
assertTrue("Expected at least " + expected.size() + " commands but found " + processor.strings.size(),
expected.size() <= processor.strings.size());
for (int i = 0; i < expected.size(); i++) {
assertEqualCommand(expected.get(i), processor.strings.get(i));
}
return compilation;
}
private void assertOnlySourceVersionWarning(Compilation compilation) {
assertThat(compilation).hadWarningCount(1);
assertThat(compilation).hadWarningContaining("Supported source version 'RELEASE_6' from annotation processor 'picocli.annotation.processing.tests");
}
private void assertEqualCommand(String expected, String actual) {
List<String> exceptions = Arrays.asList("userObject: ", "hasInitialValue: ", "initialValue: ", "# ");
Scanner expectedScanner = new Scanner(expected);
Scanner actualScanner = new Scanner(actual);
int count = 0;
NEXT_LINE: while (actualScanner.hasNextLine()) {
String actualLine = actualScanner.nextLine();
assertTrue("Unexpected actual line: " + actualLine, expectedScanner.hasNextLine());
String expectedLine = expectedScanner.nextLine();
count++;
String actLine = actualLine.trim();
String expLine = expectedLine.trim();
for (String exception : exceptions) {
if (expLine.startsWith(exception) && actLine.startsWith(exception)) {
continue NEXT_LINE;
}
}
if (expLine.startsWith("Mixin: ") && actLine.startsWith("Mixin: ")) {
continue NEXT_LINE;
}
if (expLine.startsWith("paramLabel: '<arg") && actLine.startsWith("paramLabel: '<")) {
continue NEXT_LINE;
}
if (expLine.startsWith("typeInfo: ") && actLine.startsWith("typeInfo: ")) {
assertSimilarTypeInfo(expectedLine, actualLine);
// } else if (expLine.startsWith("defaultValueProvider: ") && actLine.startsWith("defaultValueProvider: ")) {
// assertSimilarDefaultValueProvider(expectedLine, actualLine);
// } else if (expLine.startsWith("versionProvider: ") && actLine.startsWith("versionProvider: ")) {
// assertSimilarVersionProvider(expectedLine, actualLine);
} else if ((expLine.startsWith("getter: ") && actLine.startsWith("getter: ")) ||
(expLine.startsWith("setter: ") && actLine.startsWith("setter: "))) {
assertSimilarGetterSetter(expectedLine, actualLine);
} else {
if (!expectedLine.equals(actualLine)) {
assertEquals("Difference at line " + count + ": expected ["
+ expLine + "] but was [" + actLine + "]",
expected, actual);
}
}
}
if (expectedScanner.hasNextLine()) {
assertEquals("Actual is missing one or more lines after line " + count,
expected, actual);
}
}
private void assertSimilarTypeInfo(String expectedLine, String actualLine) {
final String EXPECTED_PREFIX = "typeInfo: RuntimeTypeInfo(";
final String ACTUAL_PREFIX = "typeInfo: CompileTimeTypeInfo(";
Assert.assertThat(expectedLine.trim(), startsWith(EXPECTED_PREFIX));
Assert.assertThat(actualLine.trim(), startsWith(ACTUAL_PREFIX));
String expected = expectedLine.substring(expectedLine.indexOf(EXPECTED_PREFIX) + EXPECTED_PREFIX.length());
String actual = actualLine.substring(actualLine.indexOf(ACTUAL_PREFIX) + ACTUAL_PREFIX.length());
String expected2 = expected.replace("class ", "");
Pattern pattern = Pattern.compile(".*, aux=\\[(.*)\\], collection.*");
Matcher matcher = pattern.matcher(expected2);
assertTrue(matcher.matches());
String group = matcher.group(1).replace(", ", ",");
if (!actual.startsWith(group)) {
int pos = expected2.indexOf(',');
expected2 = expected2.substring(0, pos) + "<" + group + ">" + expected2.substring(pos);
}
assertEquals(expected2, actual);
}
private void assertSimilarDefaultValueProvider(String expectedLine, String actualLine) {
if ("defaultValueProvider: null".equals(expectedLine.trim())) {
assertEquals("defaultValueProvider: DefaultValueProviderMetaData[default]", actualLine.trim());
} else {
assertEquals("Not implemented yet", expectedLine, actualLine);
}
}
private void assertSimilarVersionProvider(String expectedLine, String actualLine) {
if ("versionProvider: null".equals(expectedLine.trim())) {
assertEquals("versionProvider: VersionProviderMetaData[default]", actualLine.trim());
} else {
assertEquals("Not implemented yet", expectedLine, actualLine);
}
}
private void assertSimilarGetterSetter(String expectedLine, String actualLine) {
String expect = expectedLine.trim().substring(1);
String actual = actualLine.trim().substring(1);
if (expect.startsWith("etter: picocli.CommandLine.Model.FieldBinding")) {
Assert.assertThat(actual, startsWith(
"etter: picocli.codegen.annotation.processing.internal.GetterSetterMetaData(FIELD"));
} else if (expect.startsWith("etter: picocli.CommandLine.Model.MethodBinding")) {
Assert.assertThat(actual, startsWith(
"etter: picocli.codegen.annotation.processing.internal.GetterSetterMetaData(METHOD"));
} else if (expect.startsWith("etter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding")) {
Assert.assertThat(actual, startsWith(
"etter: picocli.codegen.annotation.processing.internal.GetterSetterMetaData(METHOD"));
} else if (expect.startsWith("etter: picocli.CommandLine.Model.ObjectBinding")) {
Assert.assertThat(actual, startsWith(
"etter: picocli.codegen.annotation.processing.internal.GetterSetterMetaData(PARAMETER"));
} else {
assertEquals("Not implemented yet", expect, actual);
}
}
}

View File

@@ -0,0 +1,74 @@
package picocli.annotation.processing.tests;
import com.google.testing.compile.Compilation;
import com.google.testing.compile.JavaFileObjects;
import org.junit.Ignore;
import org.junit.Test;
import picocli.codegen.annotation.processing.AnnotatedCommandSourceGeneratorProcessor;
import javax.tools.StandardLocation;
import static com.google.testing.compile.CompilationSubject.assertThat;
import static com.google.testing.compile.Compiler.javac;
public class AnnotatedCommandSourceGeneratorProcessorTest {
@Ignore
@Test
public void generate() {
AnnotatedCommandSourceGeneratorProcessor processor = new AnnotatedCommandSourceGeneratorProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(JavaFileObjects.forResource(
"picocli/examples/subcommands/ParentCommandDemo.java"));
assertThat(compilation).succeeded();
assertThat(compilation)
.generatedSourceFile("GeneratedHelloWorld")
.hasSourceEquivalentTo(JavaFileObjects.forResource("GeneratedHelloWorld.java"));
}
@Test
public void generate1() {
AnnotatedCommandSourceGeneratorProcessor processor = new AnnotatedCommandSourceGeneratorProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(JavaFileObjects.forResource(
"picocli/codegen/aot/graalvm/Example.java"));
assertThat(compilation).succeeded();
assertThat(compilation)
.generatedFile(StandardLocation.SOURCE_OUTPUT, "generated/picocli/codegen/aot/graalvm/Example.java")
.hasSourceEquivalentTo(JavaFileObjects.forResource("generated/picocli/codegen/aot/graalvm/Example.java"));
}
//@Ignore("TODO field constant values")
@Test
public void generateNested() {
AnnotatedCommandSourceGeneratorProcessor processor = new AnnotatedCommandSourceGeneratorProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(JavaFileObjects.forResource(
"picocli/examples/PopulateFlagsMain.java"));
assertThat(compilation).succeeded();
assertThat(compilation)
.generatedFile(StandardLocation.SOURCE_OUTPUT, "generated/picocli/examples/PopulateFlagsMain.java")
.hasSourceEquivalentTo(JavaFileObjects.forResource("generated/picocli/examples/PopulateFlagsMain.java"));
}
@Ignore
@Test
public void generateNested2() {
AnnotatedCommandSourceGeneratorProcessor processor = new AnnotatedCommandSourceGeneratorProcessor();
Compilation compilation =
javac()
.withProcessors(processor)
.compile(JavaFileObjects.forResource(
"picocli/examples/subcommands/ParentCommandDemo.java"));
assertThat(compilation).succeeded();
assertThat(compilation)
.generatedFile(StandardLocation.SOURCE_OUTPUT, "generated/examples/subcommands/ParentCommandDemo.java")
.hasSourceEquivalentTo(JavaFileObjects.forResource("generated/examples/subcommands/ParentCommandDemo.java"));
}
}

View File

@@ -0,0 +1,17 @@
usage.description = Version control system
usage.headerHeading=the headerHeading
usage.header.0=header0
usage.header.1=header1
usage.header.2=header2
usage.header.3=header3
usage.descriptionHeading=the descriptionHeading
usage.description.0=description0
usage.description.1=description1
usage.description.2=description2
usage.description.3=description3
usage.footerHeading=the footerHeading
usage.footer.0=footer0
usage.footer.1=footer1
usage.footer.2=footer2
usage.footer.3=footer3

View File

@@ -0,0 +1,49 @@
package generated.picocli.codegen.aot.graalvm;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import picocli.CommandLine.Command;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.codegen.aot.graalvm.Example.ExampleMixin;
@Command(name = "example",
mixinStandardHelpOptions = true,
subcommands = HelpCommand.class,
version = "3.7.0")
public class Example {
@Mixin ExampleMixin mixin;
@Option(names = "-t")
TimeUnit timeUnit;
@Option(names = "--minimum")
public void setMinimum(int min) {
// TODO replace the stored value with the new value
}
@Parameters(index = "0")
File file;
@Parameters(index = "1..*",
type = File.class)
public void setOtherFiles(List<File> otherFiles) {
// TODO replace the stored value with the new value
}
@Command
public static class ExampleMixin {
@Option(names = "-l")
int length;
}
@Command(name = "multiply")
int multiply(
@Option(names = "--count") int count,
@Parameters(index = "0") int multiplier) {
// TODO implement commandSpec
}
}

View File

@@ -0,0 +1,18 @@
package generated.picocli.examples;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
public class PopulateFlagsMain {
@Command
private static class Options {
@Option(names = "-b")
private boolean buffered;
@Option(names = "-o")
private boolean overwriteOutput; // TODO = true;
@Option(names = "-v")
private boolean verbose;
}
}

View File

@@ -0,0 +1,78 @@
package picocli.codegen.aot.graalvm;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.Spec;
import picocli.CommandLine.Unmatched;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Command(name = "example", version = "3.7.0",
mixinStandardHelpOptions = true, subcommands = CommandLine.HelpCommand.class)
public class Example implements Runnable {
@Command public static class ExampleMixin {
@Option(names = "-l")
int length;
}
@Option(names = "-t")
TimeUnit timeUnit;
@Parameters(index = "0")
File file;
@Spec
CommandSpec spec;
@Mixin
ExampleMixin mixin;
@Unmatched
List<String> unmatched;
private int minimum;
private List<File> otherFiles;
@Command
int multiply(@Option(names = "--count") int count,
@Parameters int multiplier) {
System.out.println("Result is " + count * multiplier);
return count * multiplier;
}
@Option(names = "--minimum")
public void setMinimum(int min) {
if (min < 0) {
throw new ParameterException(spec.commandLine(), "Minimum must be a positive integer");
}
minimum = min;
}
@Parameters(index = "1..*")
public void setOtherFiles(List<File> otherFiles) {
for (File f : otherFiles) {
if (!f.exists()) {
throw new ParameterException(spec.commandLine(), "File " + f.getAbsolutePath() + " must exist");
}
}
this.otherFiles = otherFiles;
}
public void run() {
System.out.printf("timeUnit=%s, length=%s, file=%s, unmatched=%s, minimum=%s, otherFiles=%s%n",
timeUnit, mixin.length, file, unmatched, minimum, otherFiles);
}
public static void main(String[] args) {
CommandLine.run(new Example(), args);
}
}

View File

@@ -0,0 +1,128 @@
/*
Copyright 2017 Robert 'Bobby' Zenz
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package picocli.examples;
import picocli.CommandLine;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParameterException;
/**
* This example demonstrates the usage with a simple flag class.
*
* <p>
*
* When no arguments are provided, the flags will have their default values:
*
* <pre>
* Arguments:
*
*
* Options:
* buffered: false
* overwriteOutput: true
* verbose: false
* </pre>
*
* When the flag is provided in the arguments, the default value of the flag
* will be inverted and set. So if we can provide all flags as arguments:
*
* <pre>
* Arguments:
* "-b" "-o" "-v"
*
* Options:
* buffered: true
* overwriteOutput: false
* verbose: true
* </pre>
*
* Because these flags are single letter names, we can also provide them
* concatenated in one argument:
*
* <pre>
* Arguments:
* "-bov"
*
* Options:
* buffered: true
* overwriteOutput: false
* verbose: true
* </pre>
*
* Or in any derivation there of.
*
* @author Robert 'Bobby' Zenz
*/
public class PopulateFlagsMain {
public static void main(String[] args) {
// Create a new Options class, which holds our flags.
Options options = new Options();
try {
// Populate the created class from the command line arguments.
CommandLine.populateCommand(options, args);
} catch (ParameterException e) {
// The given command line arguments are invalid, for example there
// are options specified which do not exist or one of the options
// is malformed (missing a value, for example).
System.out.println(e.getMessage());
CommandLine.usage(options, System.out);
return;
}
// Print the state.
System.out.println("Arguments:");
System.out.print(" ");
for (String arg : args) {
System.out.print("\"" + arg + "\" ");
}
System.out.println();
System.out.println();
System.out.println("Options:");
System.out.println(" buffered: " + options.isBuffered());
System.out.println(" overwriteOutput: " + options.isOverwriteOutput());
System.out.println(" verbose: " + options.isVerbose());
}
/**
* This is the main container which will be populated by picocli with values
* from the arguments.
*/
private static class Options {
@Option(names = "-b")
private boolean buffered = false;
@Option(names = "-o")
private boolean overwriteOutput; //TODO = true;
@Option(names = "-v")
private boolean verbose = false;
public boolean isBuffered() {
return buffered;
}
public boolean isOverwriteOutput() {
return overwriteOutput;
}
public boolean isVerbose() {
return verbose;
}
}
}

View File

@@ -0,0 +1,115 @@
package picocli.examples.annotatedmethods;
import picocli.CommandLine.ParameterException;
import picocli.CommandLine.PicocliException;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import static picocli.CommandLine.Option;
public class AnnotatedClassMethodOptions {
static class Primitives {
boolean aBoolean;
byte aByte;
short aShort;
int anInt;
long aLong;
float aFloat;
double aDouble;
@Option(names = "-b") void setBoolean(boolean val) { aBoolean = val; }
@Option(names = "-y") void setByte(byte val) { aByte = val; }
@Option(names = "-s") void setShort(short val) { aShort = val; }
@Option(names = "-i") void setInt(int val) { anInt = val; }
@Option(names = "-l") void setLong(long val) { aLong = val; }
@Option(names = "-f") void setFloat(float val) { aFloat = val; }
@Option(names = "-d") void setDouble(double val) { aDouble = val; }
}
static class PrimitivesWithDefault {
boolean aBoolean;
byte aByte;
short aShort;
int anInt;
long aLong;
float aFloat;
double aDouble;
@Option(names = "-b", defaultValue = "true") void setBoolean(boolean val) { aBoolean = val; }
@Option(names = "-y", defaultValue = "11") void setByte(byte val) { aByte = val; }
@Option(names = "-s", defaultValue = "12") void setShort(short val) { aShort = val; }
@Option(names = "-i", defaultValue = "13") void setInt(int val) { anInt = val; }
@Option(names = "-l", defaultValue = "14") void setLong(long val) { aLong = val; }
@Option(names = "-f", defaultValue = "15.5") void setFloat(float val) { aFloat = val; }
@Option(names = "-d", defaultValue = "16.6") void setDouble(double val) { aDouble = val; }
}
static class ObjectsWithDefaults {
Boolean aBoolean;
Byte aByte;
Short aShort;
Integer anInt;
Long aLong;
Float aFloat;
Double aDouble;
BigDecimal aBigDecimal;
String aString;
List<String> aList;
Map<Integer, Double> aMap;
SortedSet<Short> aSet;
@Option(names = "-b", defaultValue = "true") void setBoolean(Boolean val) { aBoolean = val; }
@Option(names = "-y", defaultValue = "123") void setByte(Byte val) { aByte = val; }
@Option(names = "-s", defaultValue = "11") void setShort(Short val) { aShort = val; }
@Option(names = "-i", defaultValue = "12") void setInt(Integer val) { anInt = val; }
@Option(names = "-l", defaultValue = "13") void setLong(Long val) { aLong = val; }
@Option(names = "-f", defaultValue = "14.4") void setFloat(Float val) { aFloat = val; }
@Option(names = "-d", defaultValue = "15.5") void setDouble(Double val) { aDouble = val; }
@Option(names = "-bigint", defaultValue = "16.6") void setBigDecimal(BigDecimal val) { aBigDecimal = val; }
@Option(names = "-string", defaultValue = "abc") void setString(String val) { aString = val; }
@Option(names = "-list", defaultValue = "a,b,c", split = ",") void setList(List<String> val) { aList = val; }
@Option(names = "-map", defaultValue = "1=1,2=2,3=3", split = ",")
void setMap(Map<Integer, Double> val) { aMap = val; }
@Option(names = "-set", defaultValue = "1,2,3", split = ",")
void setSortedSet(SortedSet<Short> val) { aSet = val; }
}
static class Objects {
Boolean aBoolean;
Byte aByte;
Short aShort;
Integer anInt;
Long aLong;
Float aFloat;
Double aDouble;
BigInteger aBigInteger;
String aString;
List<String> aList;
Map<Integer, Double> aMap;
SortedSet<Short> aSet;
@Option(names = "-b") void setBoolean(Boolean val) { aBoolean = val; }
@Option(names = "-y") void setByte(Byte val) { aByte = val; }
@Option(names = "-s") void setShort(Short val) { aShort = val; }
@Option(names = "-i") void setInt(Integer val) { anInt = val; }
@Option(names = "-l") void setLong(Long val) { aLong = val; }
@Option(names = "-f") void setFloat(Float val) { aFloat = val; }
@Option(names = "-d") void setDouble(Double val) { aDouble = val; }
@Option(names = "-bigint") void setBigInteger(BigInteger val) { aBigInteger = val; }
@Option(names = "-string") void setString(String val) { aString = val; }
@Option(names = "-list") void setList(List<String> val) { aList = val; }
@Option(names = "-map")
void setMap(Map<Integer, Double> val) { aMap = val; }
@Option(names = "-set")
void setSortedSet(SortedSet<Short> val) { aSet = val; }
}
}

View File

@@ -0,0 +1,140 @@
package picocli.examples.annotatedmethods;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import static picocli.CommandLine.*;
public class AnnotatedInterfaceMethodOptions {
interface Primitives {
@Option(names = "-b")
boolean aBoolean();
@Option(names = "-y")
byte aByte();
@Option(names = "-s")
short aShort();
@Option(names = "-i")
int anInt();
@Option(names = "-l")
long aLong();
@Option(names = "-f")
float aFloat();
@Option(names = "-d")
double aDouble();
}
interface PrimitivesWithDefault {
@Option(names = "-b", defaultValue = "true")
boolean aBoolean();
@Option(names = "-y", defaultValue = "11")
byte aByte();
@Option(names = "-s", defaultValue = "12")
short aShort();
@Option(names = "-i", defaultValue = "13")
int anInt();
@Option(names = "-l", defaultValue = "14")
long aLong();
@Option(names = "-f", defaultValue = "15.5")
float aFloat();
@Option(names = "-d", defaultValue = "16.6")
double aDouble();
}
interface Objects {
@Option(names = "-b")
Boolean aBoolean();
@Option(names = "-y")
Byte aByte();
@Option(names = "-s")
Short aShort();
@Option(names = "-i")
Integer anInt();
@Option(names = "-l")
Long aLong();
@Option(names = "-f")
Float aFloat();
@Option(names = "-d")
Double aDouble();
@Option(names = "-bigint")
BigInteger aBigInteger();
@Option(names = "-string")
String aString();
@Option(names = "-list")
List<String> getList();
@Option(names = "-map")
Map<Integer, Double> getMap();
@Option(names = "-set")
SortedSet<Short> getSortedSet();
}
interface ObjectsWithDefault {
@Option(names = "-b", defaultValue = "true")
Boolean aBoolean();
@Option(names = "-y", defaultValue = "123")
Byte aByte();
@Option(names = "-s", defaultValue = "11")
Short aShort();
@Option(names = "-i", defaultValue = "12")
Integer anInt();
@Option(names = "-l", defaultValue = "13")
Long aLong();
@Option(names = "-f", defaultValue = "14.4")
Float aFloat();
@Option(names = "-d", defaultValue = "15.5")
Double aDouble();
@Option(names = "-bigint", defaultValue = "16.6")
BigDecimal aBigDecimal();
@Option(names = "-string", defaultValue = "abc")
String aString();
@Option(names = "-list", defaultValue = "a,b,c", split = ",")
List<String> getList();
@Option(names = "-map", defaultValue = "1=1,2=2,3=3", split = ",")
Map<Integer, Double> getMap();
@Option(names = "-set", defaultValue = "1,2,3", split = ",")
SortedSet<Short> getSortedSet();
}
}

View File

@@ -0,0 +1,300 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: picocli.CommandLineAnnotatedMethodImplTest$Objects@2626b418
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Boolean, aux=[class java.lang.Boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<boolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setBoolean(java.lang.Boolean))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setBoolean(java.lang.Boolean))
- names: [-bigint]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.math.BigInteger, aux=[class java.math.BigInteger], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<bigInteger>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setBigInteger(java.math.BigInteger))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setBigInteger(java.math.BigInteger))
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Double, aux=[class java.lang.Double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setDouble(java.lang.Double))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setDouble(java.lang.Double))
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Float, aux=[class java.lang.Float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<float>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setFloat(java.lang.Float))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setFloat(java.lang.Float))
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Integer, aux=[class java.lang.Integer], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<int>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setInt(java.lang.Integer))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setInt(java.lang.Integer))
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Long, aux=[class java.lang.Long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<long>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setLong(java.lang.Long))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setLong(java.lang.Long))
- names: [-list]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.List, aux=[class java.lang.String], collection=true, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<list>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setList(java.util.List))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setList(java.util.List))
- names: [-map]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.Map, aux=[class java.lang.Integer, class java.lang.Double], collection=false, map=true)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<Integer=Double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setMap(java.util.Map))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setMap(java.util.Map))
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Short, aux=[class java.lang.Short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<short>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setShort(java.lang.Short))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setShort(java.lang.Short))
- names: [-set]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.SortedSet, aux=[class java.lang.Short], collection=true, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<sortedSet>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setSortedSet(java.util.SortedSet))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setSortedSet(java.util.SortedSet))
- names: [-string]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.String, aux=[class java.lang.String], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<string>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setString(java.lang.String))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setString(java.lang.String))
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Byte, aux=[class java.lang.Byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<byte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setByte(java.lang.Byte))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Objects.setByte(java.lang.Byte))
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,300 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults@2626b418
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Boolean, aux=[class java.lang.Boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'true'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<boolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setBoolean(java.lang.Boolean))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setBoolean(java.lang.Boolean))
- names: [-bigint]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.math.BigDecimal, aux=[class java.math.BigDecimal], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '16.6'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<bigDecimal>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setBigDecimal(java.math.BigDecimal))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setBigDecimal(java.math.BigDecimal))
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Double, aux=[class java.lang.Double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '15.5'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setDouble(java.lang.Double))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setDouble(java.lang.Double))
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Float, aux=[class java.lang.Float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '14.4'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<float>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setFloat(java.lang.Float))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setFloat(java.lang.Float))
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Integer, aux=[class java.lang.Integer], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '12'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<int>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setInt(java.lang.Integer))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setInt(java.lang.Integer))
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Long, aux=[class java.lang.Long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '13'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<long>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setLong(java.lang.Long))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setLong(java.lang.Long))
- names: [-list]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.List, aux=[class java.lang.String], collection=true, map=false)
arity: 1
splitRegex: ','
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'a,b,c'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<list>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setList(java.util.List))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setList(java.util.List))
- names: [-map]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.Map, aux=[class java.lang.Integer, class java.lang.Double], collection=false, map=true)
arity: 1
splitRegex: ','
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '1=1,2=2,3=3'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<Integer=Double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setMap(java.util.Map))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setMap(java.util.Map))
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Short, aux=[class java.lang.Short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '11'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<short>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setShort(java.lang.Short))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setShort(java.lang.Short))
- names: [-set]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.SortedSet, aux=[class java.lang.Short], collection=true, map=false)
arity: 1
splitRegex: ','
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '1,2,3'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<sortedSet>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setSortedSet(java.util.SortedSet))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setSortedSet(java.util.SortedSet))
- names: [-string]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.String, aux=[class java.lang.String], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'abc'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<string>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setString(java.lang.String))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setString(java.lang.String))
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Byte, aux=[class java.lang.Byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '123'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<byte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setByte(java.lang.Byte))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$ObjectsWithDefaults.setByte(java.lang.Byte))
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,195 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: picocli.CommandLineAnnotatedMethodImplTest$Primitives@2626b418
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(boolean, aux=[boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<boolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setBoolean(boolean))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setBoolean(boolean))
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(double, aux=[double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setDouble(double))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setDouble(double))
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(float, aux=[float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<float>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setFloat(float))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setFloat(float))
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<int>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setInt(int))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setInt(int))
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(long, aux=[long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<long>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setLong(long))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setLong(long))
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(short, aux=[short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<short>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setShort(short))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setShort(short))
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(byte, aux=[byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<byte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setByte(byte))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$Primitives.setByte(byte))
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,195 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault@2626b418
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(boolean, aux=[boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'true'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<boolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setBoolean(boolean))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setBoolean(boolean))
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(double, aux=[double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '16.6'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setDouble(double))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setDouble(double))
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(float, aux=[float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '15.5'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<float>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setFloat(float))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setFloat(float))
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '13'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<int>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setInt(int))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setInt(int))
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(long, aux=[long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '14'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<long>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setLong(long))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setLong(long))
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(short, aux=[short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '12'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<short>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setShort(short))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setShort(short))
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(byte, aux=[byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '11'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<byte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setByte(byte))
setter: picocli.CommandLine.Model.MethodBinding(void picocli.CommandLineAnnotatedMethodImplTest$PrimitivesWithDefault.setByte(byte))
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,300 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: null
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Boolean, aux=[class java.lang.Boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aBoolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
- names: [-bigint]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.math.BigInteger, aux=[class java.math.BigInteger], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aBigInteger>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Double, aux=[class java.lang.Double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aDouble>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Float, aux=[class java.lang.Float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aFloat>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Integer, aux=[class java.lang.Integer], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<anInt>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Long, aux=[class java.lang.Long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aLong>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
- names: [-list]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.List, aux=[class java.lang.String], collection=true, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<list>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
- names: [-map]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.Map, aux=[class java.lang.Integer, class java.lang.Double], collection=false, map=true)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<Integer=Double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@7a81197d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@7a81197d
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Short, aux=[class java.lang.Short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aShort>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5ca881b5
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5ca881b5
- names: [-set]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.SortedSet, aux=[class java.lang.Short], collection=true, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<sortedSet>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@24d46ca6
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@24d46ca6
- names: [-string]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.String, aux=[class java.lang.String], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aString>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4517d9a3
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4517d9a3
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Byte, aux=[class java.lang.Byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aByte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@372f7a8d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@372f7a8d
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,300 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: null
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Boolean, aux=[class java.lang.Boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'true'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aBoolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
- names: [-bigint]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.math.BigDecimal, aux=[class java.math.BigDecimal], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '16.6'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aBigDecimal>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Double, aux=[class java.lang.Double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '15.5'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aDouble>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Float, aux=[class java.lang.Float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '14.4'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aFloat>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Integer, aux=[class java.lang.Integer], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '12'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<anInt>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Long, aux=[class java.lang.Long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '13'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aLong>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
- names: [-list]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.List, aux=[class java.lang.String], collection=true, map=false)
arity: 1
splitRegex: ','
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'a,b,c'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<list>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
- names: [-map]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.Map, aux=[class java.lang.Integer, class java.lang.Double], collection=false, map=true)
arity: 1
splitRegex: ','
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '1=1,2=2,3=3'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<Integer=Double>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@7a81197d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@7a81197d
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Short, aux=[class java.lang.Short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '11'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aShort>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5ca881b5
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5ca881b5
- names: [-set]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.util.SortedSet, aux=[class java.lang.Short], collection=true, map=false)
arity: 1
splitRegex: ','
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '1,2,3'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<sortedSet>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@24d46ca6
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@24d46ca6
- names: [-string]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.String, aux=[class java.lang.String], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'abc'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aString>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4517d9a3
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4517d9a3
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.Byte, aux=[class java.lang.Byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '123'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<aByte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@372f7a8d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@372f7a8d
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,195 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: null
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(boolean, aux=[boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'false'
paramLabel: '<aBoolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(double, aux=[double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0.0'
paramLabel: '<aDouble>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(float, aux=[float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0.0'
paramLabel: '<aFloat>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<anInt>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(long, aux=[long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<aLong>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(short, aux=[short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<aShort>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(byte, aux=[byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<aByte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,195 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: null
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-b]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(boolean, aux=[boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'true'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'false'
paramLabel: '<aBoolean>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5a07e868
- names: [-d]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(double, aux=[double], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '16.6'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0.0'
paramLabel: '<aDouble>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@76ed5528
- names: [-f]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(float, aux=[float], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '15.5'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0.0'
paramLabel: '<aFloat>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@2c7b84de
- names: [-i]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '13'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<anInt>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@3fee733d
- names: [-l]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(long, aux=[long], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '14'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<aLong>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@5acf9800
- names: [-s]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(short, aux=[short], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '12'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<aShort>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@4617c264
- names: [-y]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(byte, aux=[byte], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: '11'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<aByte>'
converters: []
completionCandidates: null
getter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
setter: picocli.CommandLine$Model$PicocliInvocationHandler$ProxyBinding@36baf30c
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,32 @@
package picocli.examples.annotatedmethods;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import static picocli.CommandLine.*;
public class InvalidAnnotatedInterfaceMethodOptions {
// Invalid picocli annotation on interface fields
interface InvalidAnnotatedStringOrPrimitiveFields {
@Option(names = "-i")
int anInt = 0;
@Option(names = "-s")
String aString = null;
}
// Invalid picocli annotation on interface field
interface InvalidAnnotatedMutableFields {
@Option(names = "-s")
final List<String> aList = new ArrayList<String>();
}
}

View File

@@ -0,0 +1,8 @@
package picocli.example.messages.CommandWithBundle;
import picocli.CommandLine.Command;
@Command(resourceBundle = "command-method-demo")
public class CommandWithBundle {
}

View File

@@ -0,0 +1,65 @@
---
CommandSpec:
name: '<main class>'
aliases: []
userObject: picocli.example.messages.CommandWithBundle.CommandWithBundle
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options: []
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: 'the headerHeading'
header: [header0, header1, header2, header3]
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: 'the descriptionHeading'
description: [Version control system, description0, description1, description2, description3]
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: 'the footerHeading'
footer: [footer0, footer1, footer2, footer3]
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
ResourceBundle:
usage.header.0: 'header0'
usage.header.1: 'header1'
usage.headerHeading: 'the headerHeading'
usage.descriptionHeading: 'the descriptionHeading'
usage.header.2: 'header2'
usage.header.3: 'header3'
usage.footerHeading: 'the footerHeading'
usage.description.3: 'description3'
usage.footer.1: 'footer1'
usage.footer.0: 'footer0'
usage.description: 'Version control system'
usage.footer.3: 'footer3'
usage.description.0: 'description0'
usage.footer.2: 'footer2'
usage.description.1: 'description1'
usage.description.2: 'description2'
Subcommands: []

View File

@@ -0,0 +1,29 @@
package picocli.examples.mixin;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
@Command(name = "mixee", description = "This command has a footer and an option mixed in")
public class CommandWithMixin {
@Mixin
CommonOption commonOption = new CommonOption();
@Option(names = "-y", description = "command option")
int y;
@Command
public void doit(@Mixin CommonOption commonOptionParam,
@Option(names = "-z") int z,
@Parameters String arg0,
String arg1) {}
public static void main(String[] args) {
CommandWithMixin cmd = new CommandWithMixin();
new CommandLine(cmd).parseArgs("-x", "3", "-y", "4");
System.out.printf("x=%s, y=%s%n", cmd.commonOption.x, cmd.y);
}
}

View File

@@ -0,0 +1,353 @@
---
CommandSpec:
name: 'mixee'
aliases: []
userObject: picocli.examples.mixin.CommandWithMixin@31221be2
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-x]
usageHelp: false
versionHelp: false
description: [reusable option you want in many commands]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<x>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
setter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
- names: [-y]
usageHelp: false
versionHelp: false
description: [command option]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<y>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommandWithMixin.y)
setter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommandWithMixin.y)
PositionalParams: []
UnmatchedArgsBindings: []
Mixins:
# commonOption
- name: '<main class>'
aliases: []
userObject: picocli.examples.mixin.CommonOption@377dca04
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-x]
usageHelp: false
versionHelp: false
description: [reusable option you want in many commands]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<x>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
setter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: [Common footer]
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: [This command has a footer and an option mixed in]
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: [Common footer]
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands:
# doit
- name: 'doit'
aliases: []
userObject: public void picocli.examples.mixin.CommandWithMixin.doit(picocli.examples.mixin.CommonOption,int,java.lang.String,java.lang.String)
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-x]
usageHelp: false
versionHelp: false
description: [reusable option you want in many commands]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<x>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
setter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
- names: [-z]
usageHelp: false
versionHelp: false
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<arg1>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.ObjectBinding(value=0)
setter: picocli.CommandLine.Model.ObjectBinding(value=0)
PositionalParams:
- index: 0
description: []
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.lang.String, aux=[class java.lang.String], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: true
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<arg2>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.ObjectBinding(value=null)
setter: picocli.CommandLine.Model.ObjectBinding(value=null)
- index: 1
description: []
descriptionKey: 'null'
typeInfo: RuntimeTypeInfo(java.lang.String, aux=[class java.lang.String], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: true
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: false
initialValue: 'null'
paramLabel: '<arg3>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.ObjectBinding(value=null)
setter: picocli.CommandLine.Model.ObjectBinding(value=null)
UnmatchedArgsBindings: []
Mixins:
# arg0
- name: '<main class>'
aliases: []
userObject: picocli.examples.mixin.CommonOption@728938a9
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-x]
usageHelp: false
versionHelp: false
description: [reusable option you want in many commands]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(int, aux=[int], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: '0'
paramLabel: '<x>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
setter: picocli.CommandLine.Model.FieldBinding(int picocli.examples.mixin.CommonOption.x)
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: [Common footer]
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: [Common footer]
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,10 @@
package picocli.examples.mixin;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
@Command(footer = "Common footer")
public class CommonOption {
@Option(names = "-x", description = "reusable option you want in many commands")
int x;
}

View File

@@ -0,0 +1,137 @@
---
CommandSpec:
name: 'fileutils'
aliases: []
userObject: picocli.examples.subcommands.ParentCommandDemo$FileUtils@2e0fa5d3
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-d, --directory]
usageHelp: false
versionHelp: false
description: [this option applies to all subcommands]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(java.io.File, aux=[class java.io.File], collection=false, map=false)
arity: 1
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'null'
paramLabel: '<baseDirectory>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(java.io.File picocli.examples.subcommands.ParentCommandDemo.FileUtils.baseDirectory)
setter: picocli.CommandLine.Model.FieldBinding(java.io.File picocli.examples.subcommands.ParentCommandDemo.FileUtils.baseDirectory)
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands:
# list
- name: 'list'
aliases: []
userObject: picocli.examples.subcommands.ParentCommandDemo$List@5010be6
helpCommand: false
defaultValueProvider: null
versionProvider: null
version: []
Options:
- names: [-r, --recursive]
usageHelp: false
versionHelp: false
description: [Recursively list subdirectories]
descriptionKey: ''
typeInfo: RuntimeTypeInfo(boolean, aux=[boolean], collection=false, map=false)
arity: 0
splitRegex: ''
interactive: false
required: false
hidden: false
hideParamSyntax: false
defaultValue: 'null'
showDefaultValue: ON_DEMAND
hasInitialValue: true
initialValue: 'false'
paramLabel: '<recursive>'
converters: []
completionCandidates: null
getter: picocli.CommandLine.Model.FieldBinding(boolean picocli.examples.subcommands.ParentCommandDemo.List.recursive)
setter: picocli.CommandLine.Model.FieldBinding(boolean picocli.examples.subcommands.ParentCommandDemo.List.recursive)
PositionalParams: []
UnmatchedArgsBindings: []
Mixins: []
UsageMessageSpec:
width: 80
abbreviateSynopsis: false
hidden: false
showDefaultValues: false
sortOptions: true
requiredOptionMarker: ' '
headerHeading: ''
header: []
synopsisHeading: 'Usage: '
customSynopsis: []
descriptionHeading: ''
description: []
parameterListHeading: ''
optionListHeading: ''
commandListHeading: 'Commands:%n'
footerHeading: ''
footer: []
ParserSpec:
separator: '='
endOfOptionsDelimiter: '--'
expandAtFiles: true
atFileCommentChar: '#'
overwrittenOptionsAllowed: false
unmatchedArgumentsAllowed: false
unmatchedOptionsArePositionalParams: false
stopAtUnmatched: false
stopAtPositional: false
posixClusteredShortOptionsAllowed: true
aritySatisfiedByAttachedOptionParam: false
caseInsensitiveEnumValuesAllowed: false
collectErrors: false
limitSplit: false
toggleBooleanFlags: true
Subcommands: []

View File

@@ -0,0 +1,66 @@
/*
Copyright 2017 Remko Popma
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package picocli.examples.subcommands;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Option;
import picocli.CommandLine.ParentCommand;
import java.io.File;
public class ParentCommandDemo {
@Command(name = "fileutils", subcommands = List.class)
static class FileUtils implements Runnable {
@Option(names = {"-d", "--directory"}, description = "this option applies to all subcommands")
private File baseDirectory;
public void run() { System.out.println("FileUtils: my dir is " + baseDirectory); }
}
@Command(name = "list")
static class List implements Runnable {
@ParentCommand
private FileUtils parent;
@Option(names = {"-r", "--recursive"}, description = "Recursively list subdirectories")
private boolean recursive;
public void run() {
list(new File(parent.baseDirectory, ""));
}
private void list(File dir) {
System.out.println(dir.getAbsolutePath());
if (dir.isDirectory()) {
for (File f : dir.listFiles()) {
if (f.isDirectory() && recursive) {
list(f);
} else {
System.out.println(f.getAbsolutePath());
}
}
}
}
}
public static void main(String[] args) {
CommandLine.run(new FileUtils(), "--directory=examples/src", "list", "-r");
}
}

View File

@@ -0,0 +1,89 @@
package picocli.examples.validation;
import static picocli.CommandLine.Command;
import static picocli.CommandLine.Mixin;
import static picocli.CommandLine.Option;
import static picocli.CommandLine.Parameters;
import static picocli.CommandLine.ParentCommand;
import static picocli.CommandLine.Spec;
import static picocli.CommandLine.Unmatched;
@Command(subcommands = {Invalid.Sub1.class, Invalid.Sub2.class})
public class Invalid {
@Option(names = "-a")
@Parameters
int invalidOptionAndParameters;
@Mixin
int invalidPrimitiveMixin;
@Option(names = "-b")
@Mixin
Integer invalidOptionAndMixin;
@Option(names = "-c")
@Unmatched
int invalidOptionAndUnmatched;
@Option(names = "-d")
@Spec
int invalidOptionAndSpec;
@Option(names = "-e")
@ParentCommand
int invalidOptionAndParentCommand;
// ---
@Parameters
@Mixin
Integer invalidParametersAndMixin;
@Parameters
@Unmatched
int invalidParametersAndUnmatched;
@Parameters
@Spec
int invalidParametersAndSpec;
@Parameters
@ParentCommand
int invalidParametersAndParentCommand;
// ---
@Unmatched
@Mixin
Integer invalidUnmatchedAndMixin;
@Unmatched
@Spec
int invalidUnmatchedAndSpec;
@Unmatched
@ParentCommand
int invalidUnmatchedAndParentCommand;
// ---
@Spec
@Mixin
Integer invalidSpecAndMixin;
@Spec
@ParentCommand
int invalidSpecAndParentCommand;
// ---
@ParentCommand
@Mixin
Integer invalidParentCommandAndMixin;
static class Sub1 {
@Parameters String[] params;
}
@Command
static class Sub2 {
@Parameters String[] params;
}
}

View File

@@ -0,0 +1,903 @@
package picocli.codegen;
import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.ITypeConverter;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Model.ArgSpec;
import picocli.CommandLine.Model.CommandSpec;
import picocli.CommandLine.Model.ITypeInfo;
import picocli.CommandLine.Model.MethodParam;
import picocli.CommandLine.Model.OptionSpec;
import picocli.CommandLine.Model.PositionalParamSpec;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.CommandLine.ParentCommand;
import picocli.CommandLine.Spec;
import picocli.CommandLine.Unmatched;
import picocli.codegen.annotation.processing.ITypeMetaData;
import picocli.codegen.util.Assert;
import picocli.codegen.util.TypeImporter;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.ExecutableElement;
import javax.lang.model.element.PackageElement;
import javax.lang.model.element.TypeElement;
import javax.lang.model.element.VariableElement;
import javax.lang.model.type.TypeMirror;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Queue;
import java.util.Set;
import java.util.Stack;
public class AnnotatedCommandSourceGenerator {
@Command(name = "<main class>",
aliases = {},
mixinStandardHelpOptions = false,
headerHeading = "",
header = {},
descriptionHeading = "",
description = {},
synopsisHeading = "Usage: ",
abbreviateSynopsis = false,
customSynopsis = {},
optionListHeading = "",
parameterListHeading = "",
commandListHeading = "Commands:%n",
footerHeading = "",
footer = {},
requiredOptionMarker = ' ',
addMethodSubcommands = true,
subcommands = {},
version = {},
// versionProvider = null,
showDefaultValues = false,
// defaultValueProvider = null,
resourceBundle = "",
sortOptions = true,
hidden = false,
helpCommand = false,
separator = "=",
usageHelpWidth = 80)
class App {
@ParentCommand
Object parent;
@Spec
CommandSpec spec;
@Unmatched
List<String> unmatched;
@Mixin
Object mixin;
@Option(names = {},
required = false,
help = false,
usageHelp = false,
versionHelp = false,
description = {},
arity = "",
paramLabel = "",
hideParamSyntax = false,
type = {},
converter = {},
split = "",
hidden = false,
defaultValue = "__no_default_value__",
showDefaultValue = CommandLine.Help.Visibility.ON_DEMAND,
// completionCandidates = null,
interactive = false,
descriptionKey = "")
Object option;
@Parameters(index = "",
description = {},
arity = "",
paramLabel = "",
hideParamSyntax = false,
type = {},
converter = {},
split = "",
hidden = false,
defaultValue = "__no_default_value__",
showDefaultValue = CommandLine.Help.Visibility.ON_DEMAND,
// completionCandidates = null,
interactive = false,
descriptionKey = "")
Object parameter;
}
private final static String INDENT_INCREMENT = " ";
private static final String[] EMPTY_ARRAY = new String[0];
private final CommandSpec commandSpec;
private TypeImporter importer;
private String outputPackage;
public AnnotatedCommandSourceGenerator(CommandSpec commandSpec) {
this(commandSpec, extractPackageName(commandSpec.userObject()));
}
public AnnotatedCommandSourceGenerator(CommandSpec commandSpec, String outputPackage) {
this.commandSpec = Assert.notNull(commandSpec, "commandSpec");
this.outputPackage = Assert.notNull(outputPackage, "outputPackage");
this.importer = new TypeImporter(outputPackage);
}
private static String extractPackageName(Object userObject) {
if (userObject instanceof ExecutableElement) {
return extractPackageName((TypeElement) ((ExecutableElement) userObject).getEnclosingElement());
} else if (userObject instanceof TypeElement) {
return extractPackageName((TypeElement) userObject);
} else if (userObject instanceof Method) {
return extractPackageName(((Method) userObject).getDeclaringClass());
} else if (userObject instanceof Class) {
return extractPackageName((Class<?>) userObject);
} else {
return extractPackageName(userObject.getClass());
}
}
private static String extractPackageName(Class<?> cls) {
return cls.getPackage().getName();
}
private static String extractPackageName(TypeElement typeElement) {
Element enclosing = typeElement.getEnclosingElement();
while (enclosing != null) {
if (enclosing instanceof PackageElement) {
PackageElement pkg = (PackageElement) enclosing;
if (pkg.isUnnamed()) {
return "";
}
String fqcn = pkg.getQualifiedName().toString();
return fqcn;
}
enclosing = enclosing.getEnclosingElement();
}
return "";
}
public String getOutputPackage() {
return outputPackage;
}
public void setOutputPackage(String outputPackage) {
this.outputPackage = Assert.notNull(outputPackage, "outputPackage");
this.importer = new TypeImporter(outputPackage);
}
public String generate() {
StringWriter result = new StringWriter();
writeTo(new PrintWriter(result), "");
return result.toString();
}
public void writeTo(PrintWriter pw, String indent) {
StringWriter result = new StringWriter();
PrintWriter tmp = new PrintWriter(result);
printCommand(tmp, commandSpec, indent, new HashSet<Object>());
pw.println("package " + outputPackage + ";");
pw.println(importer.createImportDeclaration());
pw.println();
pw.print(result);
pw.flush();
}
private void printCommand(PrintWriter pw, CommandSpec spec, String indent, Set<Object> visited) {
Stack<String> after = new Stack<String>();
Stack<Object> surroundingElements = new Stack<Object>();
indent = printSurroundingElements(pw, spec.userObject(), indent, surroundingElements, after, visited);
printCommandAnnotation(pw, spec, indent);
pw.println();
printCommandElementDefOpen(pw, spec.userObject(), indent);
boolean isCommandMethod = isCommandMethod(spec);
String indent2 = indent + INDENT_INCREMENT;
for (String mixinName : spec.mixins().keySet()) {
CommandSpec mixin = spec.mixins().get(mixinName);
if ("picocli.CommandLine.AutoHelpMixin".equals(mixin.userObject().getClass().getCanonicalName())) {
continue;
}
pw.println();
pw.printf("%s@%s ", indent2, importer.getImportedName(Mixin.class.getCanonicalName()));
pw.print(importer.getImportedName(extractClassName(mixin.userObject())));
pw.println(" " + mixinName + ";");
}
String sep = "";
for (OptionSpec option : spec.options()) {
if (!isMixedIn(option, spec)) {
pw.printf(sep);
pw.println();
printOptionAnnotation(pw, option, indent2);
pw.printf(isCommandMethod ? " " : ("%n" + indent2));
sep = printArgElementDef(pw, option.userObject(), isCommandMethod, indent2);
}
}
for (PositionalParamSpec param : spec.positionalParameters()) {
if (!isMixedIn(param, spec)) {
pw.printf(sep);
pw.println();
printParametersAnnotation(pw, param, indent2);
pw.printf(isCommandMethod ? " " : ("%n" + indent2));
sep = printArgElementDef(pw, param.userObject(), isCommandMethod, indent2);
}
}
if (!isCommandMethod) {
pw.printf(sep);
}
for (String mixinName : spec.mixins().keySet()) {
CommandSpec mixin = spec.mixins().get(mixinName);
if (isNestedCommand(mixin, spec) && !isBuiltInMixin(mixin)) {
pw.println();
printCommand(pw, mixin, indent + INDENT_INCREMENT, visited);
}
}
for (String subcommandName : spec.subcommands().keySet()) {
CommandSpec subcommand = spec.subcommands().get(subcommandName).getCommandSpec();
if (isNestedCommand(subcommand, spec) && !isBuiltInSubcommand(subcommand)) {
pw.println();
printCommand(pw, subcommand, indent + INDENT_INCREMENT, visited);
}
}
printCommandElementDefClose(pw, spec.userObject(), indent);
while (!after.isEmpty()) {
Object surroundingElement = surroundingElements.pop();
for (String mixinName : spec.mixins().keySet()) {
CommandSpec mixin = spec.mixins().get(mixinName);
if (isNested(mixin.userObject(), surroundingElement) && !isBuiltInMixin(mixin)) {
pw.println();
printCommand(pw, mixin, indent, visited);
}
}
for (String subcommandName : spec.subcommands().keySet()) {
CommandSpec subcommand = spec.subcommands().get(subcommandName).getCommandSpec();
if (isNested(subcommand.userObject(), surroundingElement) && !isBuiltInSubcommand(subcommand)) {
pw.println();
printCommand(pw, subcommand, indent, visited);
}
}
pw.print(after.pop());
}
}
public static boolean isBuiltInMixin(CommandSpec mixin) {
String str = mixin.userObject().toString();
return "picocli.CommandLine.AutoHelpMixin".equals(str)
|| "picocli.CommandLine$AutoHelpMixin".equals(str);
}
public static boolean isBuiltInSubcommand(CommandSpec subcommand) {
String str = subcommand.userObject().toString();
return "picocli.CommandLine.HelpCommand".equals(str)
|| "picocli.CommandLine$HelpCommand".equals(str);
}
@SuppressWarnings("unchecked")
private String printSurroundingElements(PrintWriter pw,
Object userObject,
String indent,
Stack<Object> surrounding,
Stack<String> after,
Set<Object> visited) {
collectEnclosingElements(userObject, surrounding, visited);
Stack<Object> enclosing = (Stack<Object>) surrounding.clone();
Queue<String> indents = new LinkedList<String>();
for (int i = 0; i < enclosing.size(); i++) {
indents.add(indent);
indent += " ";
}
String currentIndent = indent;
Stack<String> before = new Stack<String>();
while (!enclosing.isEmpty()) {
Object obj = enclosing.pop();
currentIndent = indents.poll();
if (obj == userObject) {
break;
}
StringWriter sw = new StringWriter();
if (obj instanceof Method || obj instanceof ExecutableElement) {
printArgElementDef(new PrintWriter(sw), obj, true, currentIndent);
String definition = sw.toString();
definition = definition.substring(0, definition.indexOf("{") + 1);
before.push(String.format("%s%n", definition));
after.push(String.format("%s}%n", currentIndent));
} else {
printCommandElementDefOpen(new PrintWriter(sw), obj, currentIndent);
before.push(String.format("%s%n", sw.toString()));
sw.getBuffer().setLength(0);
printCommandElementDefClose(new PrintWriter(sw), obj, currentIndent);
after.push(sw.toString());
}
}
while (!before.isEmpty()) {
pw.print(before.pop());
}
return currentIndent;
}
private void collectEnclosingElements(Object userObject, Stack<Object> enclosing, Set<Object> visited) {
if (visited.contains(userObject)) {
return;
}
visited.add(userObject);
enclosing.add(userObject);
if (userObject instanceof Method) {
collectEnclosingElements(((Method) userObject).getDeclaringClass(), enclosing, visited);
} else if (userObject instanceof ExecutableElement) {
collectEnclosingElements(((ExecutableElement) userObject).getEnclosingElement(), enclosing, visited);
} else if (userObject instanceof Class) {
Class type = (Class) userObject;
if (type.getEnclosingMethod() != null) {
collectEnclosingElements(type.getEnclosingMethod(), enclosing, visited);
} else if (type.getDeclaringClass() != null) {
collectEnclosingElements(type.getDeclaringClass(), enclosing, visited);
}
} else if (userObject instanceof TypeElement) {
Element enclosingElement = ((TypeElement) userObject).getEnclosingElement();
if (enclosingElement instanceof TypeElement || enclosingElement instanceof ExecutableElement) {
collectEnclosingElements(enclosingElement, enclosing, visited);
}
}
}
public static boolean isNestedCommand(CommandSpec inner, CommandSpec outer) {
Object innerUserObject = inner.userObject();
Object outerUserObject = outer.userObject();
return isNested(innerUserObject, outerUserObject);
}
private static boolean isNested(Object innerUserObject, Object outerUserObject) {
if (innerUserObject instanceof Method) {
Class<?> cls = ((Method) innerUserObject).getDeclaringClass();
if (cls.equals(outerUserObject) || cls.equals(outerUserObject.getClass())) {
return true;
}
} else if (innerUserObject instanceof Element) { // ExecutableElement or TypeElement
Element enclosingElement = ((Element) innerUserObject).getEnclosingElement();
while (enclosingElement != null) {
if (enclosingElement.equals(outerUserObject)) {
return true;
}
enclosingElement = enclosingElement.getEnclosingElement();
}
return false;
} else if (innerUserObject instanceof Class) {
Class<?> cls = (Class<?>) innerUserObject;
if (cls.isMemberClass() &&
(cls.getEnclosingClass().equals(outerUserObject) || cls.getEnclosingClass().equals(outerUserObject.getClass()))) {
return true;
}
} else {
Class<?> cls = innerUserObject.getClass();
if (cls.isMemberClass() &&
(cls.getEnclosingClass().equals(outerUserObject) || cls.getEnclosingClass().equals(outerUserObject.getClass()))) {
return true;
}
}
return false;
}
private static boolean isMixedIn(OptionSpec option, CommandSpec spec) {
for (CommandSpec mixin : spec.mixins().values()) {
if (mixin.findOption(option.longestName()) != null) {
return true;
}
}
return false;
}
private static boolean isMixedIn(PositionalParamSpec positional, CommandSpec spec) {
for (CommandSpec mixin : spec.mixins().values()) {
for (PositionalParamSpec mixedIn : mixin.positionalParameters()) {
if (mixedIn.equals(positional)) {
return true;
}
}
}
return false;
}
private static String argElementName(ArgSpec argSpec) {
Object userObject = argSpec.userObject();
if (userObject instanceof Field) {
return ((Field) userObject).getName();
} else if (userObject instanceof MethodParam) {
return ((MethodParam) userObject).getName();
} else if (userObject instanceof Method) {
return propertyName(((Method) userObject).getName());
} else if (userObject instanceof VariableElement) {
return ((VariableElement) userObject).getSimpleName().toString();
} else if (userObject instanceof ExecutableElement) {
return propertyName(((ExecutableElement) userObject).getSimpleName().toString());
} else {
return userObject + "";
}
}
static String propertyName(String methodName) {
if (methodName.length() > 3 && (methodName.startsWith("get") || methodName.startsWith("set"))) { return decapitalize(methodName.substring(3)); }
return decapitalize(methodName);
}
private static String decapitalize(String name) {
if (name == null || name.length() == 0) { return name; }
char[] chars = name.toCharArray();
chars[0] = Character.toLowerCase(chars[0]);
return new String(chars);
}
private String printArgElementDef(PrintWriter pw,
Object userObject,
boolean enclosedInCommandMethod,
String indent) {
if (userObject instanceof Field) {
Field f = (Field) userObject;
String result = typeName(f.getGenericType()) + " " + f.getName();
if (f.getModifiers() != 0 && !enclosedInCommandMethod) {
pw.print(Modifier.toString(f.getModifiers()) + " " + result);
} else {
pw.print(result);
}
// default return value
} else if (userObject instanceof MethodParam) {
MethodParam param = (MethodParam) userObject;
String result = typeName(param.getParameterizedType()) + " " + param.getName();
pw.print(result);
// default return value //return ",%n";
} else if (userObject instanceof Method) {
Method m = (Method) userObject;
StringBuilder sb = new StringBuilder(128);
sb.append(typeName(m.getGenericReturnType())).append(" ").append(m.getName());
sb.append('(');
Type[] params = m.getGenericParameterTypes();
for (int j = 0; j < params.length; j++) {
String param = typeName(params[j]);
if (m.isVarArgs() && (j == params.length - 1)) {// replace T[] with T...
param = param.replaceFirst("\\[\\]$", "...");
}
sb.append(param);
sb.append(" ").append(parameterName(m, j));
if (j < (params.length - 1)) {
sb.append(',');
}
}
sb.append(')');
Type[] exceptions = m.getGenericExceptionTypes();
if (exceptions.length > 0) {
sb.append(" throws ");
for (int k = 0; k < exceptions.length; k++) {
sb.append((exceptions[k] instanceof Class)
? importer.getImportedName(((Class) exceptions[k]).getCanonicalName())
: importer.getImportedName(exceptions[k].toString())) ;
if (k < (exceptions.length - 1)) {
sb.append(',');
}
}
}
String result = sb.toString();
if (m.getModifiers() != 0 && !enclosedInCommandMethod) {
pw.print(Modifier.toString(m.getModifiers()) + " " + result);
} else {
pw.print(result);
}
if (m.getDeclaringClass().isInterface()) {
pw.print(";");
} else {
pw.println(" {");
pw.println(indent + " // TODO replace the stored value with the new value");
pw.println(indent + "}");
}
return "";
} else if (userObject instanceof VariableElement) {
VariableElement f = (VariableElement) userObject;
String result = typeName(f.asType()) + " " + f.getSimpleName();
if (!f.getModifiers().isEmpty() && !enclosedInCommandMethod) {
pw.print(modifierString(f.getModifiers()) + "" + result);
} else {
pw.print(result);
}
// default return value
} else if (userObject instanceof ExecutableElement) {
ExecutableElement m = (ExecutableElement) userObject;
StringBuilder sb = new StringBuilder(128);
sb.append(typeName(m.getReturnType())).append(" ").append(m.getSimpleName());
sb.append('(');
List<? extends VariableElement> parameters = m.getParameters();
//List<? extends TypeParameterElement> typeParameters = m.getTypeParameters();
for (int j = 0; j < parameters.size(); j++) {
String param = typeName(parameters.get(j).asType());
if (m.isVarArgs() && (j == parameters.size() - 1)) {// replace T[] with T...
param = param.replaceFirst("\\[\\]$", "...");
}
sb.append(param);
sb.append(" ").append(parameters.get(j).getSimpleName());
if (j < (parameters.size() - 1)) {
sb.append(',');
}
}
sb.append(')');
List<? extends TypeMirror> exceptions = m.getThrownTypes();
if (!exceptions.isEmpty()) {
sb.append(" throws ");
for (int k = 0; k < exceptions.size(); k++) {
sb.append(importer.getImportedName(exceptions.get(k).toString())) ;
if (k < (exceptions.size() - 1)) {
sb.append(',');
}
}
}
String result = sb.toString();
if (!m.getModifiers().isEmpty() && !enclosedInCommandMethod) {
pw.print(modifierString(m.getModifiers()) + "" + result);
} else {
pw.print(result);
}
if (m.getEnclosingElement().getKind() == ElementKind.INTERFACE) {
pw.print(";");
} else {
pw.println(" {");
pw.println(indent + " // TODO replace the stored value with the new value");
pw.println(indent + "}");
}
return "";
} else {
pw.print("CANNOT RENDER " + userObject);
}
return enclosedInCommandMethod ? "," : ";%n";
}
private String typeName(Type type) {
if (type instanceof Class) {
return importer.getImportedName(((Class<?>) type).getCanonicalName());
}
return importer.getImportedName(type.toString());
}
private String typeName(TypeMirror type) {
// StringBuilder sb = new StringBuilder();
// type.accept(new AbstractTypeVisitor6() {
//
// }, sb);
return importer.getImportedName(type.toString());
}
private static String parameterName(Method m, int j) {
try {
Object parameterArray = Method.class.getDeclaredMethod("getParameters").invoke(m);
Object parameter = Array.get(parameterArray, j);
return (String) Class.forName("java.lang.reflect.Parameter").getDeclaredMethod("getName").invoke(parameter);
} catch (Exception ignored) {}
return "arg" + j;
}
private static boolean isCommandMethod(CommandSpec spec) {
Object userObject = spec.userObject();
return userObject instanceof Method || userObject instanceof ExecutableElement;
}
private void printCommandElementDefOpen(PrintWriter pw, Object userObject, String indent) {
if (userObject instanceof Method) {
Method m = (Method) userObject;
pw.print(indent);
if (m.getModifiers() != 0) {
pw.print(Modifier.toString(m.getModifiers()));
}
pw.print(typeName(m.getGenericReturnType()));
pw.print(" ");
pw.print(m.getName());
pw.print("(");
} else if (userObject instanceof ExecutableElement) {
ExecutableElement m = (ExecutableElement) userObject;
pw.print(indent);
if (!m.getModifiers().isEmpty()) {
pw.print(modifierString(m.getModifiers()));
}
pw.print(typeName(m.getReturnType()));
pw.print(" ");
pw.print(m.getSimpleName());
pw.print("(");
} else if (userObject instanceof TypeElement) {
TypeElement type = (TypeElement) userObject;
String modifiers = modifierString(type.getModifiers());
String name = type.getSimpleName().toString();
pw.printf("%s%sclass %s {", indent, modifiers, name);
} else {
Class<?> cls = userObject.getClass();
String modifiers = cls.getModifiers() == 0 ? "" : (Modifier.toString(cls.getModifiers()) + " ");
String name = importer.getImportedName(userObject.getClass().getCanonicalName());
pw.printf("%s%sclass %s {", indent, modifiers, name);
}
}
private static String modifierString(Set<javax.lang.model.element.Modifier> modifiers) {
return modifierString(modifiers, new StringBuilder()).toString();
}
private static StringBuilder modifierString(Set<javax.lang.model.element.Modifier> modifiers, StringBuilder sb) {
for (javax.lang.model.element.Modifier mod : modifiers) {
sb.append(mod.toString());
sb.append(" ");
}
return sb;
}
private static void printCommandElementDefClose(PrintWriter pw, Object userObject, String indent) {
if (userObject instanceof Method || userObject instanceof ExecutableElement) {
String full = (userObject).toString();
pw.print(full.substring(full.indexOf(')')));
pw.println(" {");
pw.println(indent + " // TODO implement commandSpec");
pw.println(indent + "}");
} else {
pw.printf("%s}%n", indent);
}
}
private void printParametersAnnotation(PrintWriter pw, PositionalParamSpec spec, String indent) {
pw.printf("%s@%s", indent, importer.getImportedName(Parameters.class.getCanonicalName()));
indent = String.format(",%n%s ", indent);
String sep = "(";
sep = append(pw, sep, indent, "index = \"%s\"", spec.index().toString(), spec.index().isUnspecified());
sep = appendStringArray(pw, sep, indent, "description = %s", spec.description(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "arity = \"%s\"", spec.arity().toString(), spec.arity().isUnspecified() ? spec.arity().toString() : "");
sep = append(pw, sep, indent, "paramLabel = \"%s\"", spec.paramLabel(), "<" + argElementName(spec) + ">");
sep = append(pw, sep, indent, "hideParamSyntax = %s", spec.hideParamSyntax(), false);
sep = appendTypeInfo(pw, sep, indent, spec.typeInfo());
sep = appendTypeConverter(pw, sep, indent, spec.converters());
sep = append(pw, sep, indent, "split = \"%s\"", spec.splitRegex(), "");
sep = append(pw, sep, indent, "hidden = %s", spec.hidden(), false);
sep = append(pw, sep, indent, "defaultValue = \"%s\"", spec.defaultValue() == null ? "__no_default_value__" : spec.defaultValue(), "__no_default_value__");
sep = append(pw, sep, indent, "showDefaultValue = %s", spec.showDefaultValue(), CommandLine.Help.Visibility.ON_DEMAND);
sep = appendCompletionCandidates(pw, sep, indent, spec);
sep = append(pw, sep, indent, "interactive = %s", spec.interactive(), false);
sep = append(pw, sep, indent, "descriptionKey = \"%s\"", spec.descriptionKey(), "");
if (!"(".equals(sep)) {
pw.print(")");
}
}
@SuppressWarnings("deprecation")
private void printOptionAnnotation(PrintWriter pw, OptionSpec spec, String indent) {
pw.printf("%s@%s", indent, importer.getImportedName(Option.class.getCanonicalName()));
indent = String.format(",%n%s ", indent);
String sep = "(";
sep = appendStringArray(pw, sep, indent, "names = %s", spec.names(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "required = %s", spec.required(), false);
sep = append(pw, sep, indent, "help = %s", spec.help(), false);
sep = append(pw, sep, indent, "usageHelp = %s", spec.usageHelp(), false);
sep = append(pw, sep, indent, "versionHelp = %s", spec.versionHelp(), false);
sep = appendStringArray(pw, sep, indent, "description = %s", spec.description(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "arity = \"%s\"", spec.arity().toString(), spec.arity().isUnspecified() ? spec.arity().toString() : "");
sep = append(pw, sep, indent, "paramLabel = \"%s\"", spec.paramLabel(), "<" + argElementName(spec) + ">");
sep = append(pw, sep, indent, "hideParamSyntax = %s", spec.hideParamSyntax(), false);
sep = appendTypeInfo(pw, sep, indent, spec.typeInfo());
sep = appendTypeConverter(pw, sep, indent, spec.converters());
sep = append(pw, sep, indent, "split = \"%s\"", spec.splitRegex(), "");
sep = append(pw, sep, indent, "hidden = %s", spec.hidden(), false);
sep = append(pw, sep, indent, "defaultValue = %s", spec.defaultValue() == null ? "__no_default_value__" : spec.defaultValue(), "__no_default_value__");
sep = append(pw, sep, indent, "showDefaultValue = \"%s\"", spec.showDefaultValue(), CommandLine.Help.Visibility.ON_DEMAND);
sep = appendCompletionCandidates(pw, sep, indent, spec);
sep = append(pw, sep, indent, "interactive = %s", spec.interactive(), false);
sep = append(pw, sep, indent, "descriptionKey = \"%s\"", spec.descriptionKey(), "");
if (!"(".equals(sep)) {
pw.print(")");
}
}
private void printCommandAnnotation(PrintWriter pw, CommandSpec spec, String indent) {
pw.printf("%s@%s", indent, importer.getImportedName(Command.class.getCanonicalName()));
indent = String.format(",%n%s ", indent);
String sep = "(";
sep = append(pw, sep, indent, "name = \"%s\"", spec.name(), "<main class>");
sep = appendStringArray(pw, sep, indent, "aliases = %s", spec.aliases(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "mixinStandardHelpOptions = %s", spec.mixinStandardHelpOptions(), false);
sep = append(pw, sep, indent, "headerHeading = \"%s\"", spec.usageMessage().headerHeading(), "");
sep = appendStringArray(pw, sep, indent, "header = %s", spec.usageMessage().header(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "descriptionHeading = \"%s\"", spec.usageMessage().descriptionHeading(), "");
sep = appendStringArray(pw, sep, indent, "description = %s", spec.usageMessage().description(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "synopsisHeading = \"%s\"", spec.usageMessage().synopsisHeading(), "Usage: ");
sep = append(pw, sep, indent, "abbreviateSynopsis = %s", spec.usageMessage().abbreviateSynopsis(), false);
sep = appendStringArray(pw, sep, indent, "customSynopsis = %s", spec.usageMessage().customSynopsis(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "optionListHeading = \"%s\"", spec.usageMessage().optionListHeading(), "");
sep = append(pw, sep, indent, "parameterListHeading = \"%s\"", spec.usageMessage().parameterListHeading(), "");
sep = append(pw, sep, indent, "commandListHeading = \"%s\"", spec.usageMessage().commandListHeading(), "Commands:%n");
sep = append(pw, sep, indent, "footerHeading = \"%s\"", spec.usageMessage().footerHeading(), "");
sep = appendStringArray(pw, sep, indent, "footer = %s", spec.usageMessage().footer(), EMPTY_ARRAY);
sep = append(pw, sep, indent, "requiredOptionMarker = \'%s\'", spec.usageMessage().requiredOptionMarker(), ' ');
sep = append(pw, sep, indent, "addMethodSubcommands = %s", spec.isAddMethodSubcommands(), !isCommandMethod(spec));
sep = appendSubcommandClasses(pw, sep, indent, spec.subcommands());
sep = appendStringArray(pw, sep, indent, "version = %s", spec.version(), EMPTY_ARRAY);
sep = appendClassName(pw, sep, indent, "versionProvider = %s", spec.versionProvider());
sep = append(pw, sep, indent, "showDefaultValues = %s", spec.usageMessage().showDefaultValues(), false);
sep = appendClassName(pw, sep, indent, "defaultValueProvider = %s", spec.defaultValueProvider());
sep = append(pw, sep, indent, "resourceBundle = \"%s\"", spec.resourceBundleBaseName(), "null");
sep = append(pw, sep, indent, "sortOptions = %s", spec.usageMessage().sortOptions(), true);
sep = append(pw, sep, indent, "hidden = %s", spec.usageMessage().hidden(), false);
sep = append(pw, sep, indent, "helpCommand = %s", spec.helpCommand(), false);
sep = append(pw, sep, indent, "separator = \"%s\"", spec.parser().separator(), "=");
sep = append(pw, sep, indent, "usageHelpWidth = %s", spec.usageMessage().width(), 80);
if (!"(".equals(sep)) {
pw.print(")");
}
}
private static String append(PrintWriter pw,
String prefix,
String newPrefix,
String template,
Object value,
Object defaultValue) {
if (defaultValue.equals(value) || ("null".equals(defaultValue) && value == null)) {
return prefix;
}
pw.print(prefix);
pw.printf(template, value);
return newPrefix;
}
private static String appendStringArray(PrintWriter pw,
String prefix,
String newPrefix,
String template,
String[] values,
String[] defaultValues) {
if (values == null || Arrays.equals(values, defaultValues)) {
return prefix;
}
List<String> quoted = new ArrayList<String>();
for (String value : values) {
quoted.add('"' + value + '"');
}
pw.print(prefix);
pw.printf(template, listToString(quoted));
return newPrefix;
}
private String appendSubcommandClasses(PrintWriter pw,
String prefix,
String newPrefix,
Map<String, CommandLine> subcommands) {
List<String> subcommandClasses = new ArrayList<String>();
for (CommandLine cmd : subcommands.values()) {
Object obj = cmd.getCommand();
if (!(obj instanceof Method) && !(obj instanceof ExecutableElement)) {
if (obj instanceof Element) {
subcommandClasses.add(importer.getImportedName(obj.toString()) + ".class");
} else {
subcommandClasses.add(importer.getImportedName(obj.getClass().getCanonicalName()) + ".class");
}
}
}
if (subcommandClasses.isEmpty()) {
return prefix;
}
pw.print(prefix);
pw.printf("subcommands = %s", listToString(subcommandClasses));
return newPrefix;
}
private String appendClassName(PrintWriter pw,
String prefix,
String newPrefix,
String template,
Object object) {
if (object == null || isDefault(object)) {
return prefix;
}
pw.print(prefix);
pw.printf(template, extractClassName(object) + ".class");
return newPrefix;
}
private String appendTypeInfo(PrintWriter pw,
String prefix,
String newPrefix,
ITypeInfo typeInfo) {
if (typeInfo.isCollection() || typeInfo.isMap()) {
List<ITypeInfo> aux = typeInfo.getAuxiliaryTypeInfos();
pw.print(prefix);
pw.printf("type = %s", listToString(extractClassNames(aux)));
return newPrefix;
}
return prefix;
}
private List<String> extractClassNames(List<ITypeInfo> list) {
List<String> result = new ArrayList<String>();
for (ITypeInfo typeInfo : list) {
result.add(importer.getImportedName(typeInfo.getClassName()) + ".class");
}
return result;
}
private String appendTypeConverter(PrintWriter pw,
String prefix,
String newPrefix,
ITypeConverter<?>[] typeConverters) {
if (typeConverters == null) {
return prefix;
}
List<String> classNames = new ArrayList<String>();
for (ITypeConverter<?> converter : typeConverters) {
if (!isDefault(converter)) {
classNames.add(extractClassName(converter) + ".class");
}
}
if (classNames.isEmpty()) {
return prefix;
}
pw.print(prefix);
pw.printf("converter = %s", listToString(classNames));
return newPrefix;
}
private String appendCompletionCandidates(PrintWriter pw,
String prefix,
String newPrefix,
ArgSpec argSpec) {
Iterable<String> completionCandidates = argSpec.completionCandidates();
if (completionCandidates == null || isDefault(completionCandidates) || argSpec.typeInfo().isEnum()) {
return prefix;
}
pw.print(prefix);
pw.printf("completionCandidates = %s.class", extractClassName(completionCandidates));
return newPrefix;
}
private static String listToString(List<String> values) {
if (values.isEmpty()) {
return "{}";
}
if (values.size() == 1) {
return values.get(0);
}
return values.toString().replace('[', '{').replace(']', '}');
}
private static boolean isDefault(Object typeMetaData) {
return typeMetaData instanceof ITypeMetaData && ((ITypeMetaData) typeMetaData).isDefault();
}
private String extractClassName(Object object) {
if (object instanceof ITypeMetaData) {
ITypeMetaData metaData = (ITypeMetaData) object;
return importer.getImportedName(metaData.getTypeMirror().toString());
} else if (object instanceof Element) {
TypeElement typeElement = (TypeElement) object;
return importer.getImportedName(typeElement.getQualifiedName().toString());
} else {
return importer.getImportedName(object.getClass().getCanonicalName());
}
}
}

View File

@@ -0,0 +1,9 @@
package picocli.codegen;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Map;
public interface IGenerator {
void generate(OutputStream out, Map<String, ?> options) throws IOException;
}

View File

@@ -0,0 +1,155 @@
package picocli.codegen.annotation.processing;
import picocli.CommandLine.Model.CommandSpec;
import picocli.codegen.AnnotatedCommandSourceGenerator;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.Element;
import javax.lang.model.element.ElementKind;
import javax.lang.model.element.TypeElement;
import javax.tools.FileObject;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.io.Writer;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Logger;
import static javax.tools.StandardLocation.SOURCE_OUTPUT;
import static picocli.codegen.AnnotatedCommandSourceGenerator.isBuiltInMixin;
import static picocli.codegen.AnnotatedCommandSourceGenerator.isBuiltInSubcommand;
import static picocli.codegen.AnnotatedCommandSourceGenerator.isNestedCommand;
public class AnnotatedCommandSourceGeneratorProcessor extends AbstractCommandSpecProcessor {
private static Logger logger = Logger.getLogger(AnnotatedCommandSourceGeneratorProcessor.class.getName());
@Override
protected boolean handleCommands(Map<Element, CommandSpec> commands,
Set<? extends TypeElement> annotations,
RoundEnvironment roundEnv) {
List<SourceUnit> list = new ArrayList<SourceUnit>();
for (Map.Entry<Element, CommandSpec> entry : commands.entrySet()) {
SourceUnit sourceUnit = find(entry.getKey(), list);
sourceUnit.commands.add(entry.getValue());
}
for (SourceUnit sourceUnit : list) {
try {
generateCode(sourceUnit);
} catch (IOException e) {
error(sourceUnit.topLevel, "Unable to generated code for %s: %s", sourceUnit.topLevel, e);
}
}
return true;
}
private SourceUnit find(Element element, List<SourceUnit> list) {
for (SourceUnit sourceUnit : list) {
if (sourceUnit.contains(element)) {
return sourceUnit;
}
}
SourceUnit result = new SourceUnit(element);
list.add(result);
return result;
}
private void generateCode(SourceUnit sourceUnit) throws IOException {
TypeElement typeElement = (TypeElement) sourceUnit.topLevel;
int count = 0;
for (CommandSpec spec : sourceUnit.commandHierarchies()) {
AnnotatedCommandSourceGenerator generator = new AnnotatedCommandSourceGenerator(spec);
generator.setOutputPackage("generated." + generator.getOutputPackage());
String unique = count == 0 ? "" : count + "";
count++;
// create a resource to prevent recursive processing of the annotations in the generated file
FileObject sourceFile = processingEnv.getFiler().createResource(
SOURCE_OUTPUT,
generator.getOutputPackage(),
typeElement.getSimpleName() + unique + ".java");
Writer writer = null;
try {
writer = sourceFile.openWriter();
//PrintWriter pw = new PrintWriter(writer);
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
generator.writeTo(pw, "");
pw.flush();
System.out.println(sw);
writer.write(sw.toString());
writer.flush();
} finally {
if (writer != null) {
writer.close();
}
}
}
}
static class SourceUnit {
String packageName;
String className;
Element topLevel;
List<CommandSpec> commands = new ArrayList<CommandSpec>();
public SourceUnit(Element element) {
topLevel = topLevel(element);
}
public boolean contains(Element element) {
Element topLevelELement = topLevel(element);
return equals(topLevelELement, topLevel);
}
private boolean equals(Element topLevelELement, Element topLevel) {
return topLevelELement.toString().equals(topLevel.toString());
}
static Element topLevel(Element element) {
while (element.getEnclosingElement().getKind() != ElementKind.PACKAGE) {
element = element.getEnclosingElement();
}
return element;
}
public List<CommandSpec> commandHierarchies() {
List<CommandSpec> result = new ArrayList<CommandSpec>();
for (CommandSpec cmd : commands) {
String excludeReason = null;
for (CommandSpec any : commands) {
if (cmd != any && isNestedCommand(cmd, any)) {
// TODO Exclude if nested in shared surrounding element
excludeReason = "Excluding " + cmd + ": it is nested in " + any;
break;
}
if (isBuiltInMixin(cmd) || isBuiltInSubcommand(cmd)) {
excludeReason = "Excluding built-in " + cmd.userObject();
break;
}
}
if (excludeReason == null) {
result.add(cmd);
} else {
logger.info(excludeReason);
}
}
return result;
}
}
private Map<Element, CommandSpec> removeNested(Map<Element, CommandSpec> commands) {
Map<Element, CommandSpec> result = new LinkedHashMap<Element, CommandSpec>();
for (Map.Entry<Element, CommandSpec> entry : commands.entrySet()) {
CommandSpec cmd = entry.getValue();
String excludeReason = null;
}
return result;
}
}

View File

@@ -0,0 +1,34 @@
package picocli.codegen.annotation.processing;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
/**
* Abstraction over annotation attributes that take a class (or array of classes) as their value.
* For example:
* {@code @Command(defaultValueProvider = xxx.class)}
*
* @since 4.0
*/
public interface ITypeMetaData {
/**
* Returns {@code true} if the annotated element did not have the annotation attribute.
* @return {@code true} if the value is the default value.
*/
boolean isDefault();
/**
* Returns the TypeMirror of the value.
* @return the TypeMirror of the {@code @Command(defaultValueProvider = xxx.class)} annotation.
*/
TypeMirror getTypeMirror();
/**
* Returns the {@link TypeElement} of the {@link #getTypeMirror() type mirror}.
* @return the type mirror as a TypeElement
*/
TypeElement getTypeElement();
}

View File

@@ -0,0 +1,23 @@
package picocli.codegen.annotation.processing;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Formatter;
import java.util.logging.LogRecord;
class JulLogFormatter extends Formatter {
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss.SSS");
@Override
public synchronized String format(LogRecord record) {
StringBuilder sb = new StringBuilder();
sb.append(sdf.format(new Date(record.getMillis()))).append(" ");
sb.append(record.getLevel()).append(" ");
sb.append("[");
sb.append(record.getSourceClassName()).append(".").append(record.getSourceMethodName());
sb.append("] ");
sb.append(record.getMessage());
sb.append(System.getProperty("line.separator"));
return sb.toString();
}
}

View File

@@ -0,0 +1,60 @@
package picocli.codegen.annotation.processing.internal;
import picocli.codegen.annotation.processing.ITypeMetaData;
import picocli.codegen.util.Assert;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
import java.util.Iterator;
/**
* Implementation of the {@link Iterable} interface that provides metadata on the
* {@code @Command(completionCandidates = xxx.class)} annotation.
*
* @since 4.0
*/
public class CompletionCandidatesMetaData implements Iterable<String>, ITypeMetaData {
private final TypeMirror typeMirror;
public CompletionCandidatesMetaData(TypeMirror typeMirror) {
this.typeMirror = Assert.notNull(typeMirror, "typeMirror");
}
/**
* Returns {@code true} if the command did not have a {@code completionCandidates} annotation attribute.
* @return {@code true} if the command did not have a {@code completionCandidates} annotation attribute.
*/
public boolean isDefault() {
return false;
}
/**
* Returns the TypeMirror that this TypeConverterMetaData was constructed with.
* @return the TypeMirror of the {@code @Command(completionCandidates = xxx.class)} annotation.
*/
public TypeMirror getTypeMirror() {
return typeMirror;
}
public TypeElement getTypeElement() {
return (TypeElement) ((DeclaredType) typeMirror).asElement();
}
/** Always returns {@code null}. */
@Override
public Iterator<String> iterator() {
return null;
}
/**
* Returns a string representation of this object, for debugging purposes.
* @return a string representation of this object
*/
@Override
public String toString() {
return String.format("%s(%s)", getClass().getSimpleName(), isDefault() ? "default" : typeMirror);
}
}

View File

@@ -0,0 +1,61 @@
package picocli.codegen.annotation.processing.internal;
import picocli.CommandLine.IDefaultValueProvider;
import picocli.CommandLine.Model.ArgSpec;
import picocli.codegen.annotation.processing.ITypeMetaData;
import picocli.codegen.util.Assert;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
/**
* Implementation of the {@link IDefaultValueProvider} interface that provides metadata on the
* {@code @Command(defaultValueProvider = xxx.class)} annotation.
*
* @since 4.0
*/
public class DefaultValueProviderMetaData implements IDefaultValueProvider, ITypeMetaData {
private final TypeMirror typeMirror;
public DefaultValueProviderMetaData() {
this.typeMirror = null;
}
public DefaultValueProviderMetaData(TypeMirror typeMirror) {
this.typeMirror = Assert.notNull(typeMirror, "typeMirror");
}
/**
* Returns {@code true} if the command did not have a {@code defaultValueProvider} annotation attribute.
* @return {@code true} if the command did not have a {@code defaultValueProvider} annotation attribute.
*/
public boolean isDefault() {
return typeMirror == null || "picocli.CommandLine.NoDefaultProvider".equals(getTypeElement().getQualifiedName().toString());
}
/**
* Returns the TypeMirror that this DefaultValueProviderMetaData was constructed with.
* @return the TypeMirror of the {@code @Command(defaultValueProvider = xxx.class)} annotation.
*/
public TypeMirror getTypeMirror() {
return typeMirror;
}
public TypeElement getTypeElement() {
return (TypeElement) ((DeclaredType) typeMirror).asElement();
}
/** Always returns {@code null}. */
@Override
public String defaultValue(ArgSpec argSpec) { return null; }
/**
* Returns a string representation of this object, for debugging purposes.
* @return a string representation of this object
*/
@Override
public String toString() {
return String.format("%s(%s)", getClass().getSimpleName(), isDefault() ? "default" : typeMirror);
}
}

View File

@@ -0,0 +1,64 @@
package picocli.codegen.annotation.processing.internal;
import picocli.CommandLine.Model.IGetter;
import picocli.CommandLine.Model.ISetter;
import javax.lang.model.element.Element;
/**
* Implementation of the {@link IGetter} and {@link ISetter} interface that allows
* custom {@code CommandSpec} annotation processors to inspect {@code ArgSpec} objects
* to discover what program element was annotated with {@code @Option} or {@code @Parameters}.
*
* @since 4.0
*/
public class GetterSetterMetaData implements IGetter, ISetter {
private final Element element;
/**
* Constructs a new {@code GetterSetterMetaData} with the specified element
* @param element the program element annotated with {@code @Option} or {@code @Parameters}
*/
public GetterSetterMetaData(Element element) {
this.element = element;
}
/**
* Returns the program element annotated with {@code @Option} or {@code @Parameters}.
* @return the program element for an {@code ArgSpec}.
*/
public Element getElement() {
return element;
}
/**
* This implementation does nothing and always returns {@code null}.
* @param <T> ignored
* @return {@code null} always
*/
@Override
public <T> T get() {
return null;
}
/**
* This implementation does nothing.
* @param value the new value of the option or positional parameter. Ignored.
* @param <T> ignored
* @return {@code null} always
*/
@Override
public <T> T set(T value) {
return null;
}
/**
* Returns a string representation of this binding, for debugging purposes.
* @return a string representation of this binding
*/
@Override
public String toString() {
return String.format("%s(%s %s)", getClass().getCanonicalName(), element.getKind(), element);
}
}

View File

@@ -0,0 +1,57 @@
package picocli.codegen.annotation.processing.internal;
import picocli.CommandLine.ITypeConverter;
import picocli.codegen.annotation.processing.ITypeMetaData;
import picocli.codegen.util.Assert;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
/**
* Implementation of the {@link ITypeConverter} interface that provides metadata on the
* {@code @Command(typeConverter = xxx.class)} annotation.
*
* @since 4.0
*/
public class TypeConverterMetaData implements ITypeConverter, ITypeMetaData {
private final TypeMirror typeMirror;
public TypeConverterMetaData(TypeMirror typeMirror) {
this.typeMirror = Assert.notNull(typeMirror, "typeMirror");
}
/**
* Returns {@code true} if the command did not have a {@code typeConverter} annotation attribute.
* @return {@code true} if the command did not have a {@code typeConverter} annotation attribute.
*/
public boolean isDefault() {
return false;
}
/**
* Returns the TypeMirror that this TypeConverterMetaData was constructed with.
* @return the TypeMirror of the {@code @Command(typeConverter = xxx.class)} annotation.
*/
public TypeMirror getTypeMirror() {
return typeMirror;
}
public TypeElement getTypeElement() {
return (TypeElement) ((DeclaredType) typeMirror).asElement();
}
/** Always returns {@code null}. */
@Override
public Object convert(String value) { return null; }
/**
* Returns a string representation of this object, for debugging purposes.
* @return a string representation of this object
*/
@Override
public String toString() {
return String.format("%s(%s)", getClass().getSimpleName(), isDefault() ? "default" : typeMirror);
}
}

View File

@@ -0,0 +1,60 @@
package picocli.codegen.annotation.processing.internal;
import picocli.CommandLine.IVersionProvider;
import picocli.codegen.annotation.processing.ITypeMetaData;
import picocli.codegen.util.Assert;
import javax.lang.model.element.TypeElement;
import javax.lang.model.type.DeclaredType;
import javax.lang.model.type.TypeMirror;
/**
* Implementation of the {@link IVersionProvider} interface that provides metadata on the
* {@code @Command(versionProvider = xxx.class)} annotation.
*
* @since 4.0
*/
public class VersionProviderMetaData implements IVersionProvider, ITypeMetaData {
private final TypeMirror typeMirror;
public VersionProviderMetaData() {
this.typeMirror = null;
}
public VersionProviderMetaData(TypeMirror typeMirror) {
this.typeMirror = Assert.notNull(typeMirror, "typeMirror");
}
/**
* Returns {@code true} if the command did not have a {@code versionProvider} annotation attribute.
* @return {@code true} if the command did not have a {@code versionProvider} annotation attribute.
*/
public boolean isDefault() {
return typeMirror == null || "picocli.CommandLine.NoVersionProvider".equals(getTypeElement().getQualifiedName().toString());
}
/**
* Returns the TypeMirror that this VersionProviderMetaData was constructed with.
* @return the TypeMirror of the {@code @Command(versionProvider = xxx.class)} annotation.
*/
public TypeMirror getTypeMirror() {
return typeMirror;
}
public TypeElement getTypeElement() {
return (TypeElement) ((DeclaredType) typeMirror).asElement();
}
/** Always returns an empty array. */
@Override
public String[] getVersion() { return new String[0]; }
/**
* Returns a string representation of this object, for debugging purposes.
* @return a string representation of this object
*/
@Override
public String toString() {
return String.format("%s(%s)", getClass().getSimpleName(), isDefault() ? "default" : typeMirror);
}
}

View File

@@ -145,6 +145,13 @@ public class ReflectionConfigGenerator {
getOrCreateClassName("java.lang.reflect.Executable").addMethod("getParameters");
getOrCreateClassName("java.lang.reflect.Parameter").addMethod("getName");
// ANSI color enabled detection
getOrCreateClassName("java.lang.System").addMethod("console");
getOrCreateClassName("org.fusesource.jansi.AnsiConsole").addField("out");
// picocli 4.0
getOrCreateClassName("java.util.ResourceBundle").addMethod("getBaseBundleName");
// type converters registered with reflection
getOrCreateClassName("java.time.Duration").addMethod("parse", CharSequence.class);
getOrCreateClassName("java.time.Instant").addMethod("parse", CharSequence.class);

View File

@@ -0,0 +1,25 @@
package picocli.codegen.util;
/**
* Utility class providing some defensive coding convenience methods.
*/
public final class Assert {
/**
* Throws a NullPointerException if the specified object is null.
* @param object the object to verify
* @param description error message
* @param <T> type of the object to check
* @return the verified object
*/
public static <T> T notNull(T object, String description) {
if (object == null) {
throw new NullPointerException(description);
}
return object;
}
public static boolean equals(Object obj1, Object obj2) { return obj1 == null ? obj2 == null : obj1.equals(obj2); }
public static int hashCode(Object obj) {return obj == null ? 0 : obj.hashCode(); }
public static int hashCode(boolean bool) {return bool ? 1 : 0; }
private Assert() {} // private constructor: never instantiate
}

View File

@@ -0,0 +1,35 @@
package picocli.codegen.util;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public final class Resources {
public static List<String> slurpAll(String... resources) {
List<String> result = new ArrayList<String>();
for (String resource : resources) {
result.add(slurp(resource));
}
return result;
}
public static String slurp(String resource) {
try {
return slurp(Resources.class.getResource(resource).openStream());
} catch (IOException ex) {
throw new IllegalStateException(ex);
}
}
public static String slurp(InputStream in) {
Scanner s = new Scanner(in).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
private Resources() {
// utility class; don't instantiate
}
}

View File

@@ -0,0 +1,375 @@
package picocli.codegen.util;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
public class TypeImporter {
private static Set<String> javaDefaultTypes;
private Set<String> registeredPackages = new HashSet<String>();
private SortedSet<TypeName> imports = new TreeSet<TypeName>();
/**
* Creates an type importer for a compilation unit in the given package.
* @param outputPackage the package of the compilation unit
*/
public TypeImporter(String outputPackage) {
registeredPackages.add(makeValid(outputPackage));
}
/*
* Removes all code points that are not valid Java identifier parts from the given string if there is any.
* The string is returned unchanged otherwise.
*/
private static String makeValid(String s) {
StringBuilder result = new StringBuilder(s.length());
for (int ch = 0, i = 0; i < s.length(); i += Character.charCount(ch)) {
ch = s.codePointAt(i);
if (Character.isJavaIdentifierPart(ch) || ch > ' ') {
result.appendCodePoint(ch);
}
}
return result.toString();
}
public String getImportedName(String fullyQualifiedClass) {
int i = fullyQualifiedClass.indexOf('<');
if (i == -1) {
return register(fullyQualifiedClass).getSimpleName();
}
StringBuilder result = new StringBuilder();
for (int start = 0, end = fullyQualifiedClass.length(); i < end; i++) {
char c = fullyQualifiedClass.charAt(i);
switch (c) {
case ',':
case '<':
case '>':
case '&':
case '[':
case ']': {
if (start != i) {
String potentialClassName = fullyQualifiedClass.substring(start, i);
if (!isTypeVariable(potentialClassName)) {
Generic clean = new Generic(potentialClassName);
result.append(clean.specialization + register(clean.typeName).getSimpleName());
} else {
result.append(potentialClassName);
}
}
result.append(c);
start = i + 1;
break;
}
case '?': {
int j = i + 1;
while (j < end && Character.isWhitespace(fullyQualifiedClass.charAt(j))) {
j++;
}
if (j + 6 < end && "extends".equals(fullyQualifiedClass.substring(j, j + 7))) {
result.append(fullyQualifiedClass.substring(i, j + 7));
i = j + 6;
} else if (j + 4 < end && "super".equals(fullyQualifiedClass.substring(j, j + 5))) {
result.append(fullyQualifiedClass.substring(i, j + 5));
i = j + 4;
} else {
result.append(c);
}
start = i + 1;
break;
}
default: {
if (Character.isWhitespace(c) && start == i) {
result.append(c);
start++;
}
break;
}
}
}
return result.toString();
}
private boolean isTypeVariable(String potentialClassName) {
return potentialClassName.length() == 1;
}
private TypeName register(String typeName) {
return register(new TypeName(typeName));
}
private TypeName register(TypeName typeName) {
String pkg = typeName.getPackageName();
if (typeName.getSimpleName().equals("*")) {
registeredPackages.add(pkg);
imports.add(typeName);
} else if (shouldImport(typeName)) {
if ("".equals(pkg) && typeName.findMatchingSimpleName(imports) != null) {
return typeName; // already registered
}
if (!registeredPackages.contains(pkg)) {
imports.add(typeName);
}
}
return typeName;
}
/**
* Determines whether the given non-wildcard import should be added.
* By default, this returns false if the simple name is a built-in Java language type name.
*/
private boolean shouldImport(TypeName typeName) {
// don't import classes from the java.lang package
String pkg = typeName.getPackageName();
String simpleName = typeName.getSimpleName();
boolean exclude = (pkg.equals("java.lang") || pkg.equals("")) && getJavaDefaultTypes().contains(simpleName);
return !exclude;
}
/**
* Returns the set of simple names of the primitive types and types in the java.lang package
* (classes that don't need to be imported).
*/
static Set<String> getJavaDefaultTypes() {
if (javaDefaultTypes == null) {
javaDefaultTypes = Collections.unmodifiableSet(new HashSet<String>(Arrays.asList(
"AbstractMethodError",
"Appendable",
"ArithmeticException",
"ArrayIndexOutOfBoundsException",
"ArrayStoreException",
"AssertionError",
"AutoCloseable",
"Boolean",
"BootstrapMethodError",
"Byte",
"Character",
"CharSequence",
"Class",
"ClassCastException",
"ClassCircularityError",
"ClassFormatError",
"ClassLoader",
"ClassNotFoundException",
"ClassValue",
"Cloneable",
"CloneNotSupportedException",
"Comparable",
"Compiler",
"Deprecated",
"Double",
"Enum",
"EnumConstantNotPresentException",
"Error",
"Exception",
"ExceptionInInitializerError",
"Float",
"FunctionalInterface",
"IllegalAccessError",
"IllegalAccessException",
"IllegalArgumentException",
"IllegalCallerException",
"IllegalMonitorStateException",
"IllegalStateException",
"IllegalThreadStateException",
"IncompatibleClassChangeError",
"IndexOutOfBoundsException",
"InheritableThreadLocal",
"InstantiationError",
"InstantiationException",
"Integer",
"InternalError",
"InterruptedException",
"Iterable",
"LayerInstantiationException",
"LinkageError",
"Long",
"Math",
"Module",
"ModuleLayer",
"NegativeArraySizeException",
"NoClassDefFoundError",
"NoSuchFieldError",
"NoSuchFieldException",
"NoSuchMethodError",
"NoSuchMethodException",
"NullPointerException",
"Number",
"NumberFormatException",
"Object",
"OutOfMemoryError",
"Override",
"Package",
"Process",
"ProcessBuilder",
"ProcessHandle",
"Readable",
"ReflectiveOperationException",
"Runnable",
"Runtime",
"RuntimeException",
"RuntimePermission",
"SafeVarargs",
"SecurityException",
"SecurityManager",
"Short",
"StackOverflowError",
"StackTraceElement",
"StackWalker",
"StrictMath",
"String",
"StringBuffer",
"StringBuilder",
"StringIndexOutOfBoundsException",
"SuppressWarnings",
"System",
"Thread",
"ThreadDeath",
"ThreadGroup",
"ThreadLocal",
"Throwable",
"TypeNotPresentException",
"UnknownError",
"UnsatisfiedLinkError",
"UnsupportedClassVersionError",
"UnsupportedOperationException",
"VerifyError",
"VirtualMachineError",
"Void",
"boolean",
"byte",
"char",
"double",
"float",
"int",
"long",
"short",
"void")));
}
return javaDefaultTypes;
}
/**
* Returns a string with the import declarations to add to the class, using the system line separator.
*/
public String createImportDeclaration() {
return createImportDeclaration(System.getProperty("line.separator"));
}
/**
* Returns a string with the import declarations to add to the class,
* using the specified line separator to separate import lines.
*/
public String createImportDeclaration(String lineDelimiter) {
StringBuilder result = new StringBuilder();
for (TypeName importName : getImports()) {
result.append(lineDelimiter + "import " + importName + ";");
}
return result.toString();
}
private SortedSet<TypeName> getImports() {
compactImports();
return imports;
}
/*
* Removes explicit imports covered by wildcards.
*/
private void compactImports() {
Iterator<TypeName> i = imports.iterator();
while (i.hasNext()) {
TypeName importName = i.next();
if (!importName.getSimpleName().equals("*") && registeredPackages.contains(importName.getPackageName())) {
i.remove();
}
}
}
static class TypeName implements Comparable<TypeName> {
private final String qualifiedName;
private final String packageName;
private final String simpleName;
private final String importName;
TypeName(String qualifiedName) {
this.qualifiedName = qualifiedName;
String canonical = qualifiedName.replaceAll("\\$", ".");
int dot = canonical.lastIndexOf('.');
packageName = dot == -1 ? "" : makeValid(canonical.substring(0, dot));
int from = dot + 1;
int end = canonical.indexOf('[', from);
if (end == -1) {
end = canonical.length();
}
simpleName = makeValid(canonical.substring(from, end));
importName = dot == -1 ? simpleName : packageName + "." + simpleName;
}
/*
* Returns the normalized package name of this type name.
*/
private String getPackageName() {
return packageName;
}
/*
* Returns the last segment (the part following the last '.') of this type name.
* For member classes, this method returns the enclosing top-level class, <em>unless</em>
* the member class was registered by its canonical name, in which case the simple name of the member class is returned.
*/
private String getSimpleName() {
return simpleName;
}
public String getImportName() {
return importName;
}
@Override
public int compareTo(TypeName o) {
return this.qualifiedName.compareTo(o.qualifiedName);
}
@Override
public String toString() {
return qualifiedName;
}
public TypeName findMatchingSimpleName(Collection<TypeName> imports) {
for (TypeName typeName: imports) {
if (typeName.getSimpleName().equals(getSimpleName())) {
return typeName;
}
}
return null;
}
}
static class Generic {
String specialization;
String typeName;
Generic(String name) {
specialization = "";
typeName = name;
int i = name.indexOf("extends");
if (i > 0 && Character.isWhitespace(name.charAt(i - 1)) && Character.isWhitespace(name.charAt(i + + "extends".length()))) {
typeName = name.substring(i + "extends".length()).trim();
specialization = name.substring(0, name.indexOf(typeName));
}
i = name.indexOf("super");
if (i > 0 && Character.isWhitespace(name.charAt(i - 1)) && Character.isWhitespace(name.charAt(i + + "super".length()))) {
typeName = name.substring(i + "super".length()).trim();
specialization = name.substring(0, name.indexOf(typeName));
}
}
}
}

View File

@@ -0,0 +1,23 @@
package picocli.codegen;
import org.junit.Ignore;
import org.junit.Test;
import picocli.CommandLine.Model.CommandSpec;
import picocli.codegen.aot.graalvm.Example;
import picocli.codegen.util.Resources;
import static org.junit.Assert.*;
public class AnnotatedCommandSourceGeneratorTest {
@Ignore
@Test
public void generate() {
CommandSpec spec = CommandSpec.forAnnotatedObject(Example.class);
String generated = new AnnotatedCommandSourceGenerator(spec).generate();
//System.out.println(generated);
String expected = Resources.slurp("/picocli/codegen/aot/graalvm/Example.txt");
assertEquals(expected, generated);
}
}

View File

@@ -41,7 +41,7 @@ public class Example implements Runnable {
List<String> unmatched;
private int minimum;
private File[] otherFiles;
private List<File> otherFiles;
@Command
int multiply(@Option(names = "--count") int count,
@@ -59,7 +59,7 @@ public class Example implements Runnable {
}
@Parameters(index = "1..*")
public void setOtherFiles(File[] otherFiles) {
public void setOtherFiles(List<File> otherFiles) {
for (File f : otherFiles) {
if (!f.exists()) {
throw new ParameterException(spec.commandLine(), "File " + f.getAbsolutePath() + " must exist");
@@ -70,7 +70,7 @@ public class Example implements Runnable {
public void run() {
System.out.printf("timeUnit=%s, length=%s, file=%s, unmatched=%s, minimum=%s, otherFiles=%s%n",
timeUnit, mixin.length, file, unmatched, minimum, Arrays.toString(otherFiles));
timeUnit, mixin.length, file, unmatched, minimum, otherFiles);
}
public static void main(String[] args) {

View File

@@ -0,0 +1,67 @@
package picocli.codegen.util;
import org.junit.Test;
import static org.junit.Assert.*;
public class TypeImporterTest {
String[][] data = {
{"java.util.Map<java.lang.reflect.Constructor<?>, java.lang.String[]>", "Map<Constructor<?>, String[]>"},
{"my.pkg.MethodAnalysisClassVisitor<T, java.lang.reflect.Constructor<? extends java.math.BigDecimal>>", "MethodAnalysisClassVisitor<T, Constructor<? extends BigDecimal>>"},
{"my.pkg.util.IterableToCollectionSelector<E, T\textends\njava.util.Iterable<?\textends\nE>, C extends my.pkg.util.Condition1<? super E>, R extends java.util.Collection<E>>",
"IterableToCollectionSelector<E, T\textends\nIterable<?\textends\nE>, C extends Condition1<? super E>, R extends Collection<E>>"},
{"java.util.List<my.pkg.XsuperT>", "List<XsuperT>"},
{"int", "int"},
{"void", "void"},
};
@Test
public void getImportedName() {
TypeImporter importer = new TypeImporter("a.b.c");
for (String[] tuple : data) {
String actual = importer.getImportedName(tuple[0]);
assertEquals(tuple[1], actual);
}
}
@Test
public void createImportDeclaration() {
TypeImporter importer = new TypeImporter("a.b.c");
for (String[] tuple : data) {
importer.getImportedName(tuple[0]);
}
String expected = String.format("" +
"%n" +
"import java.lang.reflect.Constructor;%n" +
"import java.math.BigDecimal;%n" +
"import java.util.Collection;%n" +
"import java.util.Iterable;%n" +
"import java.util.List;%n" +
"import java.util.Map;%n" +
"import my.pkg.MethodAnalysisClassVisitor;%n" +
"import my.pkg.XsuperT;%n" +
"import my.pkg.util.Condition1;%n" +
"import my.pkg.util.IterableToCollectionSelector;");
assertEquals(expected, importer.createImportDeclaration());
}
@Test
public void createImportDeclaration1() {
TypeImporter importer = new TypeImporter("my.pkg");
for (String[] tuple : data) {
importer.getImportedName(tuple[0]);
}
String expected = "" +
"\n" +
"import java.lang.reflect.Constructor;\n" +
"import java.math.BigDecimal;\n" +
"import java.util.Collection;\n" +
"import java.util.Iterable;\n" +
"import java.util.List;\n" +
"import java.util.Map;\n" +
"import my.pkg.util.Condition1;\n" +
"import my.pkg.util.IterableToCollectionSelector;";
assertEquals(expected, importer.createImportDeclaration("\n"));
}
}

View File

@@ -26,6 +26,36 @@
{ "name" : "getName", "parameterTypes" : [] }
]
},
{
"name" : "java.lang.System",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "console", "parameterTypes" : [] }
]
},
{
"name" : "org.fusesource.jansi.AnsiConsole",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"fields" : [
{ "name" : "out" }
]
},
{
"name" : "java.util.ResourceBundle",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,
"allPublicMethods" : true,
"methods" : [
{ "name" : "getBaseBundleName", "parameterTypes" : [] }
]
},
{
"name" : "java.time.Duration",
"allDeclaredConstructors" : true,
@@ -233,7 +263,7 @@
],
"methods" : [
{ "name" : "setMinimum", "parameterTypes" : ["int"] },
{ "name" : "setOtherFiles", "parameterTypes" : ["[Ljava.io.File;"] },
{ "name" : "setOtherFiles", "parameterTypes" : ["java.util.List"] },
{ "name" : "multiply", "parameterTypes" : ["int", "int"] }
]
},
@@ -287,7 +317,7 @@
"allPublicMethods" : true
},
{
"name" : "[Ljava.io.File;",
"name" : "java.util.List",
"allDeclaredConstructors" : true,
"allPublicConstructors" : true,
"allDeclaredMethods" : true,

View File

@@ -0,0 +1,49 @@
package picocli.codegen.aot.graalvm;
import java.io.File;
import java.util.List;
import java.util.concurrent.TimeUnit;
import picocli.CommandLine.Command;
import picocli.CommandLine.HelpCommand;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
import picocli.codegen.aot.graalvm.Example.ExampleMixin;
@Command(name = "example",
mixinStandardHelpOptions = true,
subcommands = HelpCommand.class,
version = "3.7.0")
public class Example {
@Mixin ExampleMixin mixin;
@Option(names = "-t")
TimeUnit timeUnit;
@Option(names = "--minimum")
public void setMinimum(int arg0) {
// TODO replace the stored value with the new value
}
@Parameters(index = "0")
File file;
@Parameters(index = "1..*",
type = File.class)
public void setOtherFiles(List<File> arg0) {
// TODO replace the stored value with the new value
}
@Command
public static class ExampleMixin {
@Option(names = "-l")
int length;
}
@Command(name = "multiply")
int multiply(
@Option(names = "--count") int arg0,
@Parameters(index = "0") int arg1) {
// TODO implement commandSpec
}
}

View File

@@ -28,3 +28,9 @@ Application-name: $rootProject.name $project.name
"""
}
}
//tasks.withType(JavaCompile) {
// options.compilerArgs << '-Xlint:unchecked' << '-Xlint:deprecation' <<
// '-processorpath' << 'C:\\Users\\remko\\IdeaProjects\\picocli3\\picocli-codegen\\build\\libs\\picocli-codegen-4.0.0-SNAPSHOT.jar;C:\\Users\\remko\\IdeaProjects\\picocli3\\build\\libs\\picocli-4.0.0-SNAPSHOT.jar' <<
// '-processor' << 'picocli.codegen.annotation.processing.AnnotatedCommandSourceGeneratorProcessor'
//}

View File

@@ -4,6 +4,7 @@ import picocli.CommandLine;
import picocli.CommandLine.Command;
import picocli.CommandLine.Mixin;
import picocli.CommandLine.Option;
import picocli.CommandLine.Parameters;
@Command(name = "mixee", description = "This command has a footer and an option mixed in")
public class CommandWithMixin {
@@ -13,6 +14,12 @@ public class CommandWithMixin {
@Option(names = "-y", description = "command option")
int y;
@Command
public void doit(@Mixin CommonOption commonOptionParam,
@Option(names = "-z") int z,
@Parameters String arg0,
String arg1) {}
public static void main(String[] args) {
CommandWithMixin cmd = new CommandWithMixin();
new CommandLine(cmd).parseArgs("-x", "3", "-y", "4");

View File

@@ -3,4 +3,5 @@ include 'picocli-examples'
include 'picocli-shell-jline2'
include 'picocli-shell-jline3'
include 'picocli-codegen'
include 'picocli-annotation-processing-tests'

File diff suppressed because it is too large Load Diff

View File

@@ -3,10 +3,15 @@ package picocli;
import org.junit.Test;
import picocli.CommandLine.Model.IGetter;
import picocli.CommandLine.Model.ISetter;
import picocli.CommandLine.Model.ITypeInfo;
import picocli.CommandLine.Model.PositionalParamSpec;
import picocli.CommandLine.Model.RuntimeTypeInfo;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.*;
import static org.junit.Assert.assertArrayEquals;
@@ -192,4 +197,46 @@ public class ModelArgSpecTest {
assertEquals(candidates, positional.completionCandidates());
}
@Test
public void testArgSpecBuilderInferLabel() throws Exception{
Method m = CommandLine.Model.ArgSpec.Builder.class.getDeclaredMethod("inferLabel", String.class, String.class, ITypeInfo.class);
m.setAccessible(true);
assertEquals("<String=String>", m.invoke(null, "", "fieldName", typeInfo(new Class[0])));
assertEquals("<String=String>", m.invoke(null, "", "fieldName", typeInfo(new Class[]{Integer.class})));
assertEquals("<String=String>", m.invoke(null, "", "fieldName", typeInfo(new Class[]{null, Integer.class})));
assertEquals("<String=String>", m.invoke(null, "", "fieldName", typeInfo(new Class[]{Integer.class, null})));
assertEquals("<Integer=Integer>", m.invoke(null, "", "fieldName", typeInfo(new Class[]{Integer.class, Integer.class})));
}
private ITypeInfo typeInfo(final Class<?>[] aux) {
return new TypeInfoAdapter() {
public boolean isMap() { return true; }
public List<ITypeInfo> getAuxiliaryTypeInfos() {
List<ITypeInfo> result = new ArrayList<ITypeInfo>();
for (final Class<?> c : aux) {
if (c == null) { result.add(null); }
result.add(new TypeInfoAdapter() {
public String getClassSimpleName() { return c.getSimpleName(); }
});
}
return result;
}
};
}
static class TypeInfoAdapter implements ITypeInfo {
public boolean isMap() { return false; }
public List<ITypeInfo> getAuxiliaryTypeInfos() { return null; }
public List<String> getActualGenericTypeArguments() { return null; }
public boolean isBoolean() { return false; }
public boolean isMultiValue() { return false; }
public boolean isArray() { return false; }
public boolean isCollection() { return false; }
public boolean isEnum() { return false; }
public List<String> getEnumConstantNames() { return null; }
public String getClassName() { return null; }
public String getClassSimpleName() { return null; }
public Class<?> getType() { return null; }
public Class<?>[] getAuxiliaryTypes() { return new Class[0]; }
}
}

View File

@@ -1,37 +0,0 @@
package picocli;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class ModelArgsReflectionTest {
@Test
public void testInstantiatable() {
new CommandLine.Model.ArgsReflection(); // no error
}
@Test
public void testInferLabel() throws Exception{
Method m = CommandLine.Model.ArgsReflection.class.getDeclaredMethod("inferLabel", String.class, String.class, Class.class, Class[].class);
m.setAccessible(true);
assertEquals("<String=String>", m.invoke(null, "", "fieldName", Map.class, new Class[0]));
assertEquals("<String=String>", m.invoke(null, "", "fieldName", Map.class, new Class[]{Integer.class}));
assertEquals("<String=String>", m.invoke(null, "", "fieldName", Map.class, new Class[]{null, Integer.class}));
assertEquals("<String=String>", m.invoke(null, "", "fieldName", Map.class, new Class[]{Integer.class, null}));
assertEquals("<Integer=Integer>", m.invoke(null, "", "fieldName", Map.class, new Class[]{Integer.class, Integer.class}));
}
@Test
public void testInferTypes() {
class App {
@CommandLine.Parameters
List<Class<? extends Class<? extends String>[]>> list;
}
assertEquals("<list>", CommandLine.Model.CommandSpec.forAnnotatedObject(new App()).positionalParameters().get(0).paramLabel());
}
}

View File

@@ -89,7 +89,7 @@ public class ModelCommandReflectionTest {
@Test
public void testValidateUnmatched() throws Exception {
Class<?> reflection = Class.forName("picocli.CommandLine$Model$CommandReflection");
Method validateUnmatched = reflection.getDeclaredMethod("validateUnmatched", CommandLine.Model.TypedMember.class);
Method validateUnmatched = reflection.getDeclaredMethod("validateUnmatched", CommandLine.Model.IAnnotatedElement.class);
validateUnmatched.setAccessible(true);
CommandLine.Model.TypedMember typedMember = new CommandLine.Model.TypedMember(TypedMemberObj.class.getDeclaredField("x"));

View File

@@ -19,7 +19,7 @@ public class ModelMessagesTest {
@Test
public void testMessagesCopyNonNull() {
Messages orig = new Messages(CommandSpec.create(), null);
Messages orig = new Messages(CommandSpec.create(), (ResourceBundle) null);
Messages copy = Messages.copy(CommandSpec.create(), orig);
assertNull(copy.resourceBundle());
}
@@ -27,21 +27,21 @@ public class ModelMessagesTest {
@Test
public void testMessagesCommandSpec() {
CommandSpec spec = CommandSpec.create();
Messages orig = new Messages(spec, null);
Messages orig = new Messages(spec, (ResourceBundle) null);
assertSame(spec, orig.commandSpec());
}
@Test
public void testMessagesEmpty() {
assertTrue(Messages.empty((Messages) null));
assertTrue(Messages.empty(new Messages(CommandSpec.create(), null)));
assertTrue(Messages.empty(new Messages(CommandSpec.create(), (ResourceBundle) null)));
}
@Test
public void testMessagesGetStringNullKey() {
String def = "abc";
assertSame(def, new Messages(CommandSpec.create(), null).getString(null, def));
assertSame(def, new Messages(CommandSpec.create(), null).getString("help", def));
assertSame(def, new Messages(CommandSpec.create(), (ResourceBundle) null).getString(null, def));
assertSame(def, new Messages(CommandSpec.create(), (ResourceBundle) null).getString("help", def));
ResourceBundle rb = ResourceBundle.getBundle("picocli.SharedMessages");
assertSame(def, new Messages(CommandSpec.create(), rb).getString(null, def));
@@ -52,8 +52,8 @@ public class ModelMessagesTest {
@Test
public void testMessagesGetStringArrayNullKey() {
String[] def = {"abc"};
assertSame(def, new Messages(CommandSpec.create(), null).getStringArray(null, def));
assertSame(def, new Messages(CommandSpec.create(), null).getStringArray("help", def));
assertSame(def, new Messages(CommandSpec.create(), (ResourceBundle) null).getStringArray(null, def));
assertSame(def, new Messages(CommandSpec.create(), (ResourceBundle) null).getStringArray("help", def));
ResourceBundle rb = ResourceBundle.getBundle("picocli.SharedMessages");
assertSame(def, new Messages(CommandSpec.create(), rb).getStringArray(null, def));

View File

@@ -33,7 +33,7 @@ public class ModelTestUtil {
return option(obj, fieldName, CommandLine.defaultFactory());
}
public static OptionSpec option(Object obj, String fieldName, CommandLine.IFactory factory) throws Exception {
return ArgsReflection.extractOptionSpec(TypedMember.createIfAnnotated(obj.getClass().getDeclaredField(fieldName), obj), factory);
return OptionSpec.builder(TypedMember.createIfAnnotated(obj.getClass().getDeclaredField(fieldName), obj), factory).build();
}
public static OptionSpec[] options(Object obj, String... fieldNames) throws Exception {
OptionSpec[] result = new OptionSpec[fieldNames.length];

View File

@@ -0,0 +1,21 @@
package picocli;
import org.junit.Test;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
import static org.junit.Assert.assertEquals;
public class ModelTypedMemberTest {
@Test
public void testInferTypes() {
class App {
@CommandLine.Parameters
List<Class<? extends Class<? extends String>[]>> list;
}
assertEquals("<list>", CommandLine.Model.CommandSpec.forAnnotatedObject(new App()).positionalParameters().get(0).paramLabel());
}
}