Skip to content

Commit fa04447

Browse files
committed
fix combination errors
1 parent 1041544 commit fa04447

File tree

2 files changed

+91
-19
lines changed

2 files changed

+91
-19
lines changed

core/src/main/java/net/jbock/compiler/Param.java

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,7 @@
1111
import javax.lang.model.element.TypeElement;
1212
import javax.lang.model.type.TypeKind;
1313
import javax.lang.model.type.TypeMirror;
14-
import java.util.Arrays;
15-
import java.util.Collections;
16-
import java.util.List;
17-
import java.util.Optional;
18-
import java.util.OptionalInt;
19-
import java.util.stream.Stream;
14+
import java.util.*;
2015

2116
import static java.lang.Character.isWhitespace;
2217
import static net.jbock.compiler.AnnotationUtil.getCollectorClass;
@@ -113,7 +108,6 @@ private Param(
113108
OptionType paramType,
114109
ExecutableElement sourceMethod,
115110
String name,
116-
boolean positional,
117111
String bundleKey, Coercion coercion,
118112
List<String> description,
119113
String descriptionArgumentName,
@@ -147,16 +141,6 @@ private Param(
147141
throw ValidationException.create(sourceMethod, "Declare a flag, or use a custom mapper.");
148142
}
149143
}
150-
if (Stream.of(optional, repeatable, flag).mapToInt(Param::booleanToInt).sum() >= 2) {
151-
throw ValidationException.create(sourceMethod, "Only one of optional, repeatable and flag can be true.");
152-
}
153-
if (positional && positionalOrder() == null) {
154-
throw new AssertionError("positional, but positionalType is null");
155-
}
156-
}
157-
158-
private static int booleanToInt(boolean b) {
159-
return b ? 1 : 0;
160144
}
161145

162146
FieldSpec field() {
@@ -199,6 +183,15 @@ private static Param createNonpositional(
199183
boolean optional = parameter.optional();
200184
boolean flag = parameter.flag();
201185
boolean required = !repeatable && !optional && !flag;
186+
if (optional && repeatable) {
187+
throw ValidationException.create(sourceMethod, "A parameter can be either repeatable or optional, but not both.");
188+
}
189+
if (optional && flag) {
190+
throw ValidationException.create(sourceMethod, "A flag cannot be declared optional.");
191+
}
192+
if (repeatable && flag) {
193+
throw ValidationException.create(sourceMethod, "A flag cannot be declared repeatable.");
194+
}
202195
if (flag && mapperClass != null) {
203196
throw ValidationException.create(sourceMethod,
204197
"A flag parameter can't have a mapper.");
@@ -215,7 +208,6 @@ private static Param createNonpositional(
215208
type,
216209
sourceMethod,
217210
name,
218-
false,
219211
parameter.bundleKey(),
220212
typeInfo,
221213
cleanDesc(description),
@@ -238,6 +230,9 @@ private static Param createPositional(
238230
boolean repeatable = parameter.repeatable();
239231
boolean optional = parameter.optional();
240232
boolean required = !repeatable && !optional;
233+
if (optional && repeatable) {
234+
throw ValidationException.create(sourceMethod, "A parameter can be either repeatable or optional, but not both.");
235+
}
241236
Coercion coercion = CoercionProvider.getInstance().findCoercion(sourceMethod, name, mapperClass, collectorClass, repeatable, optional);
242237
OptionType type = optionType(repeatable, false);
243238
String descriptionArgumentName = parameter.descriptionArgumentName().isEmpty() ?
@@ -250,7 +245,6 @@ private static Param createPositional(
250245
type,
251246
sourceMethod,
252247
name,
253-
true,
254248
parameter.bundleKey(),
255249
coercion,
256250
cleanDesc(description),
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
package net.jbock.compiler;
2+
3+
import org.junit.jupiter.api.Test;
4+
5+
import javax.tools.JavaFileObject;
6+
import java.util.ArrayList;
7+
import java.util.Arrays;
8+
import java.util.Collections;
9+
import java.util.List;
10+
11+
import static com.google.common.truth.Truth.assertAbout;
12+
import static com.google.testing.compile.JavaFileObjects.forSourceLines;
13+
import static com.google.testing.compile.JavaSourcesSubjectFactory.javaSources;
14+
import static java.util.Collections.singletonList;
15+
import static net.jbock.compiler.ProcessorTest.withImports;
16+
17+
class CombinationTest {
18+
19+
@Test
20+
void repeatableFlag() {
21+
List<String> sourceLines = withImports(
22+
"@CommandLineArguments",
23+
"abstract class InvalidArguments {",
24+
" @Parameter(shortName = 'x', repeatable = true, flag = true)",
25+
" abstract List<String> a();",
26+
"}");
27+
JavaFileObject javaFile = forSourceLines("test.InvalidArguments", sourceLines);
28+
assertAbout(javaSources()).that(singletonList(javaFile))
29+
.processedWith(new Processor())
30+
.failsToCompile()
31+
.withErrorContaining("A flag cannot be declared repeatable.");
32+
}
33+
34+
@Test
35+
void optionalFlag() {
36+
List<String> sourceLines = withImports(
37+
"@CommandLineArguments",
38+
"abstract class InvalidArguments {",
39+
" @Parameter(shortName = 'x', optional = true, flag = true)",
40+
" abstract String a();",
41+
"}");
42+
JavaFileObject javaFile = forSourceLines("test.InvalidArguments", sourceLines);
43+
assertAbout(javaSources()).that(singletonList(javaFile))
44+
.processedWith(new Processor())
45+
.failsToCompile()
46+
.withErrorContaining("A flag cannot be declared optional.");
47+
}
48+
49+
@Test
50+
void optionalRepeatable() {
51+
List<String> sourceLines = withImports(
52+
"@CommandLineArguments",
53+
"abstract class InvalidArguments {",
54+
" @Parameter(shortName = 'x', repeatable = true, optional = true)",
55+
" abstract String a();",
56+
"}");
57+
JavaFileObject javaFile = forSourceLines("test.InvalidArguments", sourceLines);
58+
assertAbout(javaSources()).that(singletonList(javaFile))
59+
.processedWith(new Processor())
60+
.failsToCompile()
61+
.withErrorContaining("A parameter can be either repeatable or optional, but not both.");
62+
}
63+
64+
@Test
65+
void positionalOptionalRepeatable() {
66+
List<String> sourceLines = withImports(
67+
"@CommandLineArguments",
68+
"abstract class InvalidArguments {",
69+
" @PositionalParameter(repeatable = true, optional = true)",
70+
" abstract String a();",
71+
"}");
72+
JavaFileObject javaFile = forSourceLines("test.InvalidArguments", sourceLines);
73+
assertAbout(javaSources()).that(singletonList(javaFile))
74+
.processedWith(new Processor())
75+
.failsToCompile()
76+
.withErrorContaining("A parameter can be either repeatable or optional, but not both.");
77+
}
78+
}

0 commit comments

Comments
 (0)