Skip to content

Commit 827d608

Browse files
committed
reject unknown tokens if OtherTokens is not present
1 parent b7845ad commit 827d608

File tree

5 files changed

+52
-16
lines changed

5 files changed

+52
-16
lines changed

README.md

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ abstract class CurlArguments {
6868
@Description({
6969
"@OtherTokens to capture all other tokens in the input.",
7070
"In this case, everything that isn't a '-v' flag",
71-
"or immediately follows after a '-H' or '-X' token."})
71+
"or immediately follows after a '-H' or '-X' token.",
72+
"If no method carries the @OtherTokens annotation,",
73+
"such a token will trigger an IllegalArgumentException."})
7274
abstract List<String> urls();
7375
}
7476
````
@@ -129,7 +131,7 @@ and then deleting this file using `rm`.
129131
<dependency>
130132
<groupId>com.github.h908714124</groupId>
131133
<artifactId>jbock</artifactId>
132-
<version>2.2</version>
134+
<version>2.2.1</version>
133135
<scope>provided</scope>
134136
</dependency>
135137
````
@@ -152,7 +154,7 @@ For Java 9 users, one more config is currently necessary until
152154
<dependency>
153155
<groupId>com.github.h908714124</groupId>
154156
<artifactId>jbock</artifactId>
155-
<version>2.2</version>
157+
<version>2.2.1</version>
156158
</dependency>
157159
</annotationProcessorPaths>
158160

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

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ private Analyser(Processor.Context context) {
106106
.addModifiers(PRIVATE, FINAL)
107107
.build();
108108
this.readOption = readOptionMethod(keysClass, longNames, shortNames, option.optionClass);
109-
this.read = readMethod(keysClass, readOption, readArgument, optMapType, sMapType, flagsType,
109+
this.read = readMethod(context, keysClass, readOption, readArgument, optMapType, sMapType, flagsType,
110110
option.optionClass, optionType, optionTypeClass, removeFirstFlag);
111111
}
112112

@@ -258,6 +258,7 @@ private static MethodSpec readArgumentMethod() {
258258
}
259259

260260
private static MethodSpec readMethod(
261+
Context context,
261262
ClassName keysClass,
262263
MethodSpec readOption,
263264
MethodSpec readArgument,
@@ -281,14 +282,27 @@ private static MethodSpec readMethod(
281282
ParameterSpec token = ParameterSpec.builder(STRING, "token").build();
282283
ParameterSpec option = ParameterSpec.builder(optionClass, "option").build();
283284
ParameterSpec ignore = ParameterSpec.builder(optionClass, "__").build();
284-
//@formatter:off
285+
285286
CodeBlock.Builder builder = CodeBlock.builder()
286287
.addStatement("$T $N = $N", STRING, token, originalToken)
287-
.addStatement("$T $N = $N($N, $N)", option.type, option, readOption, names, token)
288-
.beginControlFlow("if ($N == null)", option)
289-
.addStatement("$N.add($N)", otherTokens, token)
290-
.addStatement("return")
291-
.endControlFlow()
288+
.addStatement("$T $N = $N($N, $N)", option.type, option, readOption, names, token);
289+
290+
// @formatter:off
291+
// handle "other" token
292+
builder.beginControlFlow("if ($N == null)", option);
293+
if (context.otherTokens) {
294+
builder.addStatement("$N.add($N)", otherTokens, token)
295+
.addStatement("return");
296+
} else {
297+
builder.addStatement("throw new $T($S + $N)", IllegalArgumentException.class,
298+
"Unknown token: ", originalToken);
299+
}
300+
builder.endControlFlow();
301+
// @formatter:on
302+
303+
// @formatter:off
304+
// handle flag or option group
305+
builder
292306
.beginControlFlow("while ($N.$N == $T.$L)", option, optionType, optionTypeClass, OptionType.FLAG)
293307
.beginControlFlow("if (!$N.add($N))", flags, option)
294308
.add(repetitionErrorInGroup(option, originalToken))
@@ -302,7 +316,12 @@ private static MethodSpec readMethod(
302316
.addStatement("throw new $T($S + $N)", IllegalArgumentException.class,
303317
"Missing value after token: ", originalToken)
304318
.endControlFlow()
305-
.endControlFlow()
319+
.endControlFlow();
320+
// @formatter:on
321+
322+
// @formatter:off
323+
// handle option
324+
builder
306325
.addStatement("$T $N = $N($N, $N)", argument.type, argument, readArgument, token, it)
307326
.beginControlFlow("if ($N.$N == $T.$L)", option, optionType, optionTypeClass, OptionType.OPTIONAL)
308327
.beginControlFlow("if ($N.containsKey($N))", sMap, option)
@@ -321,8 +340,8 @@ private static MethodSpec readMethod(
321340
bucket.type, bucket, optMap, option, ignore, ArrayList.class)
322341
.addStatement("$N.add($N)", bucket, argument)
323342
.endControlFlow();
343+
// @formatter:on
324344

325-
//@formatter:on
326345
return MethodSpec.methodBuilder("read")
327346
.addParameters(Arrays.asList(originalToken, names, optMap, sMap, flags, otherTokens, it))
328347
.addModifiers(STATIC, PRIVATE)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final class Param {
2121

2222
private final String longName;
2323
private final String shortName;
24-
private final OptionType optionType;
24+
final OptionType optionType;
2525

2626
private final String stopword;
2727

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

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -233,24 +233,27 @@ static final class Context {
233233
final ClassName generatedClass;
234234
final List<Param> parameters;
235235
final String stopword;
236+
final boolean otherTokens;
236237

237238
private Context(
238239
TypeElement sourceType,
239240
ClassName generatedClass,
240241
List<Param> parameters,
241-
String stopword) {
242+
String stopword, boolean otherTokens) {
242243
this.sourceType = sourceType;
243244
this.generatedClass = generatedClass;
244245
this.parameters = parameters;
245246
this.stopword = stopword;
247+
this.otherTokens = otherTokens;
246248
}
247249

248250
private static Context create(
249251
TypeElement sourceType,
250252
List<Param> parameters,
251253
String stopword) {
252254
ClassName generatedClass = peer(ClassName.get(asType(sourceType)), SUFFIX);
253-
return new Context(sourceType, generatedClass, parameters, stopword);
255+
boolean otherTokens = parameters.stream().anyMatch(p -> p.optionType == OptionType.OTHER_TOKENS);
256+
return new Context(sourceType, generatedClass, parameters, stopword, otherTokens);
254257
}
255258

256259
TypeName returnType() {

examples/src/test/java/net/zerobuilder/examples/gradle/NoNameTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,17 @@
33
import static org.assertj.core.api.Assertions.assertThat;
44

55
import java.util.Optional;
6+
import org.junit.Rule;
67
import org.junit.Test;
8+
import org.junit.rules.ExpectedException;
79

810
public class NoNameTest {
911

12+
@Rule
13+
public final ExpectedException exception = ExpectedException.none();
14+
1015
@Test
11-
public void test() throws Exception {
16+
public void test() {
1217
NoName noName = NoName_Parser.parse(new String[]{"--message=m", "--file=f", "--file=o",
1318
"--file=o", "--cmos"});
1419
assertThat(noName.cmos()).isEqualTo(true);
@@ -18,4 +23,11 @@ public void test() throws Exception {
1823
assertThat(noName.file().get(1)).isEqualTo("o");
1924
assertThat(noName.file().get(2)).isEqualTo("o");
2025
}
26+
27+
@Test
28+
public void errorUnknownToken() {
29+
exception.expect(IllegalArgumentException.class);
30+
exception.expectMessage("Unknown token: blabla");
31+
NoName noName = NoName_Parser.parse(new String[]{"blabla"});
32+
}
2133
}

0 commit comments

Comments
 (0)