Allow for use of named suggestion providers in @Flag annotated command method parameters, add methods to FlagContext to work with flag values as optionals

This commit is contained in:
jmp 2020-11-01 13:38:08 -08:00 committed by Alexander Söderberg
parent 6d0301d9dd
commit fc1a613463
10 changed files with 104 additions and 30 deletions

View file

@ -23,6 +23,8 @@
//
package cloud.commandframework.annotations;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -41,14 +43,14 @@ public @interface Argument {
*
* @return Argument name
*/
String value();
@NonNull String value();
/**
* Name of the argument parser
*
* @return Argument name
*/
String parserName() default "";
@NonNull String parserName() default "";
/**
* Name of the suggestions provider to use. If the string is left empty, the default
@ -64,20 +66,20 @@ public @interface Argument {
* should be used instead
* @since 1.1.0
*/
String suggestions() default "";
@NonNull String suggestions() default "";
/**
* Get the default value
*
* @return Default value
*/
String defaultValue() default "";
@NonNull String defaultValue() default "";
/**
* The argument description
*
* @return Argument description
*/
String description() default "";
@NonNull String description() default "";
}

View file

@ -24,6 +24,7 @@
package cloud.commandframework.annotations;
import cloud.commandframework.arguments.parser.StandardParameters;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
@ -42,6 +43,6 @@ public @interface CommandDescription {
*
* @return Command syntax
*/
String value() default "";
@NonNull String value() default "";
}

View file

@ -23,6 +23,8 @@
//
package cloud.commandframework.annotations;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -40,13 +42,13 @@ public @interface CommandMethod {
*
* @return Command syntax
*/
String value();
@NonNull String value();
/**
* The required sender
*
* @return Required sender
*/
Class<?> requiredSender() default Object.class;
@NonNull Class<?> requiredSender() default Object.class;
}

View file

@ -23,6 +23,8 @@
//
package cloud.commandframework.annotations;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@ -40,6 +42,6 @@ public @interface CommandPermission {
*
* @return Command permission
*/
String value() default "";
@NonNull String value() default "";
}

View file

@ -23,15 +23,21 @@
//
package cloud.commandframework.annotations;
import org.checkerframework.checker.nullness.qual.NonNull;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.util.function.BiFunction;
/**
* Indicates that the parameter should be treated like a {@link cloud.commandframework.arguments.flags.CommandFlag}.
* If the parameter is a {@code boolean} then a presence flag will be created, else a value flag will be created
* and the parser will be resolved the same way as it would for a {@link Argument}
* <ul>
* <li>If the parameter is a {@code boolean}, a presence flag will be created</li>
* <li>If the parameter is of any other type, a value flag will be created and the parser
* will resolve it in the same way that it would for an {@link Argument}</li>
* </ul>
*/
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
@ -42,14 +48,14 @@ public @interface Flag {
*
* @return Flag name
*/
String value();
@NonNull String value();
/**
* Flag aliases
*
* @return Aliases
*/
String[] aliases() default "";
@NonNull String[] aliases() default "";
/**
* Name of the parser. Leave empty to use
@ -57,13 +63,29 @@ public @interface Flag {
*
* @return Parser name
*/
String parserName() default "";
@NonNull String parserName() default "";
/**
* Name of the suggestions provider to use. If the string is left empty, the default
* provider for the argument parser will be used. Otherwise,
* the {@link cloud.commandframework.arguments.parser.ParserRegistry} instance in the
* {@link cloud.commandframework.CommandManager} will be queried for a matching suggestion provider.
* <p>
* For this to work, the suggestion needs to be registered in the parser registry. To do this, use
* {@link cloud.commandframework.arguments.parser.ParserRegistry#registerSuggestionProvider(String, BiFunction)}.
* The registry instance can be retrieved using {@link cloud.commandframework.CommandManager#getParserRegistry()}.
*
* @return The name of the suggestion provider, or {@code ""} if the default suggestion provider for the argument parser
* should be used instead
* @since 1.2.0
*/
@NonNull String suggestions() default "";
/**
* The argument description
*
* @return Argument description
*/
String description() default "";
@NonNull String description() default "";
}

View file

@ -37,6 +37,8 @@ import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Collection;
import java.util.LinkedList;
import java.util.List;
import java.util.function.BiFunction;
import java.util.function.Function;
final class FlagExtractor implements Function<@NonNull Method, Collection<@NonNull CommandFlag<?>>> {
@ -78,14 +80,25 @@ final class FlagExtractor implements Function<@NonNull Method, Collection<@NonNu
parameter.getType().getCanonicalName(), flag.value(), method.getName()
));
}
final CommandArgument.Builder argumentBuilder = CommandArgument.ofType(
final BiFunction<?, @NonNull String, @NonNull List<String>> suggestionProvider;
if (!flag.suggestions().isEmpty()) {
suggestionProvider = registry.getSuggestionProvider(flag.suggestions()).orElse(null);
} else {
suggestionProvider = null;
}
final CommandArgument.Builder argumentBuilder0 = CommandArgument.ofType(
parameter.getType(),
flag.value()
);
final CommandArgument argument = argumentBuilder.asRequired()
final CommandArgument.Builder argumentBuilder = argumentBuilder0.asRequired()
.manager(this.commandManager)
.withParser(parser)
.build();
.withParser(parser);
final CommandArgument argument;
if (suggestionProvider != null) {
argument = argumentBuilder.withSuggestionsProvider(suggestionProvider).build();
} else {
argument = argumentBuilder.build();
}
flags.add(builder.withArgument(argument).build());
}
}