mirror of
https://github.com/jlengrand/picocli.git
synced 2026-03-10 08:41:17 +00:00
[#1137] Fix ClassCastException in annotation processor when an option has completionCandidates
Closes #1137
This commit is contained in:
@@ -22,6 +22,7 @@ Picocli follows [semantic versioning](http://semver.org/).
|
||||
* [#1124] Enhancement: automatically generate a better summary in the `AutoComplete.GenerateCompletion` generated man page.
|
||||
* [#1126] Enhancement: Make picocli trace levels case-insensitive.
|
||||
* [#1128] Enhancement: `ParameterException` caused by `TypeConversionException` now have their cause exception set.
|
||||
* [#1137] Bugfix: The `picocli-codegen` annotation processor causes the build to fail with a `ClassCastException` when an option has `completionCandidates` defined.
|
||||
* [#1127] DOC: Custom ShortErrorMessageHandler manual example should use bold red for error message.
|
||||
* [#1130] DOC: Clarify how to run picocli-based applications.
|
||||
* [#1131] DOC: Add anchor links before section titles in user manual.
|
||||
|
||||
@@ -225,15 +225,8 @@ public class CommandSpecYamlPrinter {
|
||||
}
|
||||
|
||||
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();
|
||||
// cannot list actual completion candidates: class cannot be instantiated at compile time
|
||||
return String.valueOf(iterable);
|
||||
}
|
||||
|
||||
@Command(name = "CommandSpecYamlPrinter", mixinStandardHelpOptions = true,
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
package picocli.annotation.processing.tests;
|
||||
|
||||
import com.google.testing.compile.Compilation;
|
||||
import com.google.testing.compile.JavaFileObjects;
|
||||
import org.junit.Test;
|
||||
|
||||
import javax.annotation.processing.Processor;
|
||||
import javax.tools.StandardLocation;
|
||||
|
||||
import static com.google.testing.compile.CompilationSubject.assertThat;
|
||||
import static com.google.testing.compile.Compiler.javac;
|
||||
import static picocli.annotation.processing.tests.Resources.slurp;
|
||||
import static picocli.annotation.processing.tests.YamlAssert.compareCommandYamlDump;
|
||||
|
||||
public class Issue1137Test {
|
||||
@Test
|
||||
public void testIssue1137() {
|
||||
Processor processor = new AnnotatedCommandSourceGeneratorProcessor();
|
||||
Compilation compilation =
|
||||
javac()
|
||||
.withProcessors(processor)
|
||||
.compile(JavaFileObjects.forResource(
|
||||
"picocli/issue1137/Issue1137.java"));
|
||||
|
||||
assertThat(compilation).succeeded();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testIssue1137Details() {
|
||||
|
||||
Compilation compilation = compareCommandYamlDump(slurp("/picocli/issue1137/Issue1137.yaml"),
|
||||
JavaFileObjects.forResource("picocli/issue1137/Issue1137.java"));
|
||||
|
||||
assertOnlySourceVersionWarning(compilation);
|
||||
}
|
||||
|
||||
private void assertOnlySourceVersionWarning(Compilation compilation) {
|
||||
assertThat(compilation).hadWarningCount(0); // #826 version warnings are now suppressed
|
||||
// assertThat(compilation).hadWarningContaining("Supported source version 'RELEASE_6' from annotation processor 'picocli.annotation.processing.tests");
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package picocli.issue1137;
|
||||
|
||||
import picocli.CommandLine;
|
||||
import picocli.CommandLine.Command;
|
||||
import picocli.CommandLine.Model.CommandSpec;
|
||||
import picocli.CommandLine.Option;
|
||||
import picocli.CommandLine.Spec;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.ArrayList;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
@Command(name = "top",
|
||||
version = {"test 1.0"},
|
||||
resourceBundle = "mybundle5")
|
||||
public class Issue1137 implements Callable<Integer> {
|
||||
|
||||
@CommandLine.Option(names = "--level",
|
||||
description = "Level.",
|
||||
defaultValue = "OFF",
|
||||
showDefaultValue = CommandLine.Help.Visibility.ALWAYS,
|
||||
completionCandidates = LevelCompletion.class)
|
||||
private String level;
|
||||
|
||||
@Spec
|
||||
CommandSpec spec;
|
||||
|
||||
@Override
|
||||
public Integer call() throws Exception {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public static class LevelCompletion extends ArrayList<String> {
|
||||
public LevelCompletion() {
|
||||
super(Arrays.asList("OFF", "INFO", "WARN"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
---
|
||||
CommandSpec:
|
||||
name: 'top'
|
||||
aliases: []
|
||||
userObject: picocli.issue1137.Issue1137
|
||||
helpCommand: false
|
||||
defaultValueProvider: null
|
||||
versionProvider: null
|
||||
version: [test 1.0]
|
||||
ArgGroups: []
|
||||
Options:
|
||||
- names: [--level]
|
||||
usageHelp: false
|
||||
versionHelp: false
|
||||
description: [Level.]
|
||||
descriptionKey: ''
|
||||
typeInfo: CompileTimeTypeInfo(java.lang.String, aux=[java.lang.String], collection=false, map=false)
|
||||
arity: 1
|
||||
splitRegex: ''
|
||||
interactive: false
|
||||
required: false
|
||||
hidden: false
|
||||
hideParamSyntax: false
|
||||
defaultValue: 'OFF'
|
||||
showDefaultValue: ALWAYS
|
||||
hasInitialValue: false
|
||||
initialValue: 'null'
|
||||
paramLabel: '<level>'
|
||||
converters: []
|
||||
completionCandidates: CompletionCandidatesMetaData(picocli.issue1137.Issue1137.LevelCompletion)
|
||||
getter: AnnotatedElementHolder(FIELD level in picocli.issue1137.Issue1137)
|
||||
setter: AnnotatedElementHolder(FIELD level in picocli.issue1137.Issue1137)
|
||||
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: false
|
||||
Subcommands: []
|
||||
@@ -41,7 +41,7 @@ class CompletionCandidatesMetaData implements Iterable<String>, ITypeMetaData {
|
||||
for (ExecutableElement attribute : elementValues.keySet()) {
|
||||
if ("completionCandidates".equals(attribute.getSimpleName().toString())) {
|
||||
AnnotationValue typeMirror = elementValues.get(attribute);
|
||||
return new CompletionCandidatesMetaData((TypeMirror) typeMirror);
|
||||
return new CompletionCandidatesMetaData((TypeMirror) typeMirror.getValue());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -72,7 +72,7 @@ class CompletionCandidatesMetaData implements Iterable<String>, ITypeMetaData {
|
||||
/** Always returns {@code null}. */
|
||||
@Override
|
||||
public Iterator<String> iterator() {
|
||||
return null;
|
||||
throw new UnsupportedOperationException("Cannot instantiate " + typeMirror + " at compile time.");
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user