✨ Allow for class annotations as a default for when an annotation is not present on a method
This commit is contained in:
parent
d37f2236e7
commit
c9d4f39612
7 changed files with 40 additions and 19 deletions
|
|
@ -24,6 +24,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
### Changed
|
||||
- Allow for combined presence flags, such that `-a -b -c` is equivalent to `-abc`
|
||||
- Allow for class annotations as a default for when an annotation is not present on a method.
|
||||
|
||||
## [1.0.2] - 2020-10-18
|
||||
|
||||
|
|
|
|||
|
|
@ -106,6 +106,25 @@ public final class AnnotationParser<C> {
|
|||
));
|
||||
}
|
||||
|
||||
protected static <A extends Annotation> @Nullable A getMethodOrClassAnnotation(
|
||||
final @NonNull Method method,
|
||||
final @NonNull Class<A> clazz
|
||||
) {
|
||||
if (method.isAnnotationPresent(clazz)) {
|
||||
return method.getAnnotation(clazz);
|
||||
} else if (method.getDeclaringClass().isAnnotationPresent(clazz)) {
|
||||
return method.getDeclaringClass().getAnnotation(clazz);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected static <A extends Annotation> boolean methodOrClassHasAnnotation(
|
||||
final @NonNull Method method,
|
||||
final @NonNull Class<A> clazz
|
||||
) {
|
||||
return getMethodOrClassAnnotation(method, clazz) != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an annotation mapper
|
||||
*
|
||||
|
|
@ -186,8 +205,8 @@ public final class AnnotationParser<C> {
|
|||
final String commandToken = commandMethod.value().split(" ")[0].split("\\|")[0];
|
||||
@SuppressWarnings("ALL") final CommandManager manager = this.manager;
|
||||
final SimpleCommandMeta.Builder metaBuilder = SimpleCommandMeta.builder()
|
||||
.with(this.metaFactory.apply(method.getAnnotations()));
|
||||
if (method.isAnnotationPresent(Confirmation.class)) {
|
||||
.with(this.metaFactory.apply(method));
|
||||
if (methodOrClassHasAnnotation(method, Confirmation.class)) {
|
||||
metaBuilder.with(CommandConfirmationManager.CONFIRMATION_REQUIRED_META, "true");
|
||||
}
|
||||
|
||||
|
|
@ -245,8 +264,9 @@ public final class AnnotationParser<C> {
|
|||
}
|
||||
}
|
||||
|
||||
if (method.isAnnotationPresent(CommandPermission.class)) {
|
||||
builder = builder.permission(method.getAnnotation(CommandPermission.class).value());
|
||||
final CommandPermission commandPermission = getMethodOrClassAnnotation(method, CommandPermission.class);
|
||||
if (commandPermission != null) {
|
||||
builder = builder.permission(commandPermission.value());
|
||||
}
|
||||
|
||||
if (commandMethod.requiredSender() != Object.class) {
|
||||
|
|
@ -263,7 +283,7 @@ public final class AnnotationParser<C> {
|
|||
throw new RuntimeException("Failed to construct command execution handler", e);
|
||||
}
|
||||
/* Check if the command should be hidden */
|
||||
if (method.isAnnotationPresent(Hidden.class)) {
|
||||
if (methodOrClassHasAnnotation(method, Hidden.class)) {
|
||||
builder = builder.hidden();
|
||||
}
|
||||
/* Apply flags */
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ import java.lang.annotation.Target;
|
|||
* Maps to {@link StandardParameters#DESCRIPTION}
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
public @interface CommandDescription {
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ import java.lang.annotation.Target;
|
|||
/**
|
||||
* Equivalent to {@link cloud.commandframework.Command.Builder#permission(String)}
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface CommandPermission {
|
||||
|
||||
|
|
|
|||
|
|
@ -32,7 +32,7 @@ import java.lang.annotation.Target;
|
|||
* Require confirmation for the command
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
public @interface Confirmation {
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,7 @@ import java.lang.annotation.Target;
|
|||
/**
|
||||
* Indicates that the command should be hidden. Similar to {@link Command.Builder#hidden()}
|
||||
*/
|
||||
@Target(ElementType.METHOD)
|
||||
@Target({ElementType.METHOD, ElementType.TYPE})
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface Hidden {
|
||||
|
||||
|
|
|
|||
|
|
@ -28,9 +28,10 @@ import cloud.commandframework.meta.CommandMeta;
|
|||
import org.checkerframework.checker.nullness.qual.NonNull;
|
||||
|
||||
import java.lang.annotation.Annotation;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.function.Function;
|
||||
|
||||
class MetaFactory implements Function<@NonNull Annotation @NonNull [], @NonNull CommandMeta> {
|
||||
class MetaFactory implements Function<@NonNull Method, @NonNull CommandMeta> {
|
||||
|
||||
private final AnnotationParser<?> annotationParser;
|
||||
private final Function<ParserParameters, CommandMeta> metaMapper;
|
||||
|
|
@ -44,17 +45,16 @@ class MetaFactory implements Function<@NonNull Annotation @NonNull [], @NonNull
|
|||
}
|
||||
|
||||
@Override
|
||||
public @NonNull CommandMeta apply(final @NonNull Annotation @NonNull [] annotations) {
|
||||
public @NonNull CommandMeta apply(final @NonNull Method method) {
|
||||
final ParserParameters parameters = ParserParameters.empty();
|
||||
for (final Annotation annotation : annotations) {
|
||||
@SuppressWarnings("ALL") final Function function = this.annotationParser.getAnnotationMappers()
|
||||
.get(annotation.annotationType());
|
||||
if (function == null) {
|
||||
continue;
|
||||
}
|
||||
this.annotationParser.getAnnotationMappers().forEach(((annotationClass, mapper) -> {
|
||||
final Annotation annotation = AnnotationParser.getMethodOrClassAnnotation(method, annotationClass);
|
||||
if (annotation != null) {
|
||||
@SuppressWarnings("ALL") final Function function = (Function) mapper;
|
||||
//noinspection unchecked
|
||||
parameters.merge((ParserParameters) function.apply(annotation));
|
||||
}
|
||||
}));
|
||||
return this.metaMapper.apply(parameters);
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue