Feature: Allow argument names to be inferred from parameter names

This commit is contained in:
Alexander Söderberg 2021-10-02 11:49:02 +02:00 committed by Jason
parent 83163c2a77
commit ad80933a20
5 changed files with 37 additions and 9 deletions

View file

@ -79,6 +79,11 @@ import java.util.function.Function;
*/
public final class AnnotationParser<C> {
/**
* The value of {@link Argument} that should be used to infer argument names from parameter names.
*/
public static final String INFERRED_ARGUMENT_NAME = "__INFERRED_ARGUMENT_NAME__";
private final SyntaxParser syntaxParser = new SyntaxParser();
private final ArgumentExtractor argumentExtractor = new ArgumentExtractor();
@ -438,7 +443,7 @@ public final class AnnotationParser<C> {
for (final ArgumentParameterPair argumentPair : arguments) {
final CommandArgument<C, ?> argument = this.buildArgument(
method,
this.findSyntaxFragment(tokens, argumentPair.getArgument().value()),
this.findSyntaxFragment(tokens, argumentPair.argumentName()),
argumentPair
);
commandArguments.put(argument.getName(), argument);
@ -606,13 +611,13 @@ public final class AnnotationParser<C> {
if (syntaxFragment == null || syntaxFragment.getArgumentMode() == ArgumentMode.LITERAL) {
throw new IllegalArgumentException(String.format(
"Invalid command argument '%s' in method '%s': "
+ "Missing syntax mapping", argumentPair.getArgument().value(), method.getName()));
+ "Missing syntax mapping", argumentPair.argumentName(), method.getName()));
}
final Argument argument = argumentPair.getArgument();
/* Create the argument builder */
@SuppressWarnings("rawtypes") final CommandArgument.Builder argumentBuilder = CommandArgument.ofType(
parameter.getType(),
argument.value()
argumentPair.argumentName()
);
/* Set the argument requirement status */
if (syntaxFragment.getArgumentMode() == ArgumentMode.OPTIONAL) {

View file

@ -39,11 +39,17 @@ import java.util.function.BiFunction;
public @interface Argument {
/**
* Argument name
* The name of the argument that this parameter is bound to.
* This value must be overridden unless you have explicitly enabled
* the preservation of parameter names in your compiler options.
*
* If the parameter names are preserved and the name of the bound
* argument is the same as the parameter name, the default value
* may be used.
*
* @return Argument name
*/
@NonNull String value();
@NonNull String value() default AnnotationParser.INFERRED_ARGUMENT_NAME;
/**
* Name of the argument parser

View file

@ -48,4 +48,12 @@ final class ArgumentParameterPair {
return this.argument;
}
@NonNull String argumentName() {
if (this.argument.value().equals(AnnotationParser.INFERRED_ARGUMENT_NAME)) {
return this.parameter.getName();
} else {
return this.argument.value();
}
}
}

View file

@ -105,11 +105,19 @@ public class MethodCommandExecutionHandler<C> implements CommandExecutionHandler
for (final Parameter parameter : this.parameters) {
if (parameter.isAnnotationPresent(Argument.class)) {
final Argument argument = parameter.getAnnotation(Argument.class);
final CommandArgument<C, ?> commandArgument = this.context.commandArguments.get(argument.value());
if (commandArgument.isRequired()) {
arguments.add(commandContext.get(argument.value()));
final String argumentName;
if (argument.value().equals(AnnotationParser.INFERRED_ARGUMENT_NAME)) {
argumentName = parameter.getName();
} else {
final Object optional = commandContext.getOptional(argument.value()).orElse(null);
argumentName = argument.value();
}
final CommandArgument<C, ?> commandArgument = this.context.commandArguments.get(argumentName);
if (commandArgument.isRequired()) {
arguments.add(commandContext.get(argumentName));
} else {
final Object optional = commandContext.getOptional(argumentName).orElse(null);
arguments.add(optional);
}
} else if (parameter.isAnnotationPresent(Flag.class)) {