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

@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Added `executeFuture` to `CommandExecutionHandler` which is now used internally. By default, this delegates to the old
`execute` method
- Annotations: Apply builder modifiers from class annotations ([#303](https://github.com/Incendo/cloud/pull/303))
- Annotations: Add default value to `@Argument`, which will force the parser to infer the argument name from the parameter name
### Fixed
- Bukkit: Permission checking and syntax string for Bukkit '/help' command

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)) {