Skip to content

Commit

Permalink
Refactor argument api and create flow.
Browse files Browse the repository at this point in the history
  • Loading branch information
Rollczi committed Sep 21, 2023
1 parent 7da9a78 commit e161768
Show file tree
Hide file tree
Showing 142 changed files with 1,138 additions and 1,674 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import dev.rollczi.litecommands.LiteCommands;
import dev.rollczi.litecommands.adventure.LiteAdventureExtension;
import dev.rollczi.litecommands.annotations.LiteAnnotationCommands;
import dev.rollczi.litecommands.join.JoinArgument;
import dev.rollczi.litecommands.programmatic.LiteCommand;
import dev.rollczi.litecommands.programmatic.LiteCommandsProgrammatic;
import dev.rollczi.litecommands.join.Join;
Expand Down Expand Up @@ -43,9 +44,8 @@ public void onEnable() {
new ConvertCommand()
))
.commands(LiteCommandsProgrammatic.of(

new LiteCommand<CommandSender>("ban")
.permission("example.ban")
.permissions("example.ban")
.argument("player", Player.class)
.onExecute(context -> {
Player player = context.argument("player", Player.class);
Expand All @@ -63,7 +63,7 @@ public void onEnable() {
// Suggestions, if you want you can override default argument suggesters
.argumentSuggester(String.class, SuggestionResult.of("name", "argument"))
.argumentSuggester(Integer.class, SuggestionResult.of("1", "2", "3"))
.argumentSuggester(String.class, Join.ARGUMENT_KEY, SuggestionResult.of("Simple suggestion", "Simple suggestion 2"))
.argumentSuggester(String.class, JoinArgument.KEY, SuggestionResult.of("Simple suggestion", "Simple suggestion 2"))

// Context resolver for @Context Player
.context(Player.class, new BukkitOnlyPlayerContextual<>("&cOnly player can execute this command!"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.command.Command;
import dev.rollczi.litecommands.command.executor.Execute;
import dev.rollczi.litecommands.execute.Execute;
import dev.rollczi.litecommands.permission.Permission;
import org.bukkit.entity.Player;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package dev.rollczi.example.bukkit.command;

import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.command.executor.Execute;
import dev.rollczi.litecommands.execute.Execute;
import dev.rollczi.litecommands.permission.Permission;
import dev.rollczi.litecommands.command.Command;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.context.Context;
import dev.rollczi.litecommands.command.executor.Execute;
import dev.rollczi.litecommands.execute.Execute;
import dev.rollczi.litecommands.permission.Permission;
import dev.rollczi.litecommands.command.Command;
import org.bukkit.GameMode;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.context.Context;
import dev.rollczi.litecommands.command.executor.Execute;
import dev.rollczi.litecommands.execute.Execute;
import dev.rollczi.litecommands.permission.Permission;
import dev.rollczi.litecommands.command.Command;
import org.bukkit.Location;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import dev.rollczi.litecommands.LiteCommands;
import dev.rollczi.litecommands.annotations.LiteAnnotationCommands;
import dev.rollczi.litecommands.join.Join;
import dev.rollczi.litecommands.join.JoinArgument;
import dev.rollczi.litecommands.suggestion.SuggestionResult;
import dev.rollczi.litecommands.schematic.SchematicFormat;
import dev.rollczi.litecommands.velocity.LiteVelocityFactory;
Expand Down Expand Up @@ -54,7 +55,7 @@ public void onProxyInitialization(ProxyInitializeEvent event) {
// Suggestions, if you want you can override default argument suggesters
.argumentSuggester(String.class, SuggestionResult.of("name", "argument"))
.argumentSuggester(Integer.class, SuggestionResult.of("1", "2", "3"))
.argumentSuggester(String.class, Join.ARGUMENT_KEY, SuggestionResult.of("Simple suggestion", "Simple suggestion 2"))
.argumentSuggester(String.class, JoinArgument.KEY, SuggestionResult.of("Simple suggestion", "Simple suggestion 2"))

// Context resolvers @Context
.context(Player.class, new VelocityOnlyPlayerContextual<>("&cOnly player can execute this command!"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.velocitypowered.api.proxy.Player;
import com.velocitypowered.api.proxy.server.RegisteredServer;
import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.command.executor.Execute;
import dev.rollczi.litecommands.execute.Execute;
import dev.rollczi.litecommands.command.Command;
import net.kyori.adventure.text.minimessage.MiniMessage;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import dev.rollczi.litecommands.annotations.LiteAnnotationCommands;
import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.command.Command;
import dev.rollczi.litecommands.command.executor.Execute;
import dev.rollczi.litecommands.execute.Execute;
import dev.rollczi.litecommands.unit.AssertExecute;
import dev.rollczi.litecommands.unit.LiteCommandsTestFactory;
import dev.rollczi.litecommands.unit.TestPlatform;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package dev.rollczi.litecommands.argument;
package dev.rollczi.litecommands.annotation;

import dev.rollczi.litecommands.annotation.AnnotationHolder;
import dev.rollczi.litecommands.argument.Argument;

import java.lang.annotation.Annotation;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package dev.rollczi.litecommands.annotation;

import dev.rollczi.litecommands.requirement.Requirement;

import java.lang.annotation.Annotation;

class ArgumentRequirementFactory<SENDER, A extends Annotation> implements RequirementFactory<A> {

private final ArgumentFactory<A> argumentFactory;

public ArgumentRequirementFactory(ArgumentFactory<A> argumentFactory) {
this.argumentFactory = argumentFactory;
}

@Override
public <PARSED> Requirement<PARSED> create(AnnotationHolder<A, PARSED, ?> holder) {
return argumentFactory.create(holder);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package dev.rollczi.litecommands.annotation;

import dev.rollczi.litecommands.requirement.Requirement;

import java.lang.annotation.Annotation;

class ContextRequirementFactory<A extends Annotation> implements RequirementFactory<A> {

@Override
public <PARSED> Requirement<PARSED> create(AnnotationHolder<A, PARSED, ?> holder) {
return new ContextRequirementImpl<>(holder);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
package dev.rollczi.litecommands.annotation;

import dev.rollczi.litecommands.meta.Meta;
import dev.rollczi.litecommands.meta.MetaHolder;
import dev.rollczi.litecommands.annotation.AnnotationHolder;
import dev.rollczi.litecommands.requirement.ContextRequirement;
import dev.rollczi.litecommands.wrapper.WrapFormat;
import org.jetbrains.annotations.Nullable;

import java.lang.annotation.Annotation;

class ContextRequirementImpl<PARSED, A extends Annotation> implements ContextRequirement<PARSED> {

private final AnnotationHolder<A, PARSED, ?> holder;
private final Meta meta = Meta.create();

ContextRequirementImpl(AnnotationHolder<A, PARSED, ?> holder) {
this.holder = holder;
}

@Override
public String getName() {
return this.holder.getName();
}

@Override
public WrapFormat<PARSED, ?> getWrapperFormat() {
return holder.getFormat();
}


@Override
public Meta meta() {
return meta;
}

@Override
public @Nullable MetaHolder parentMeta() {
return null;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package dev.rollczi.litecommands.annotation;

import dev.rollczi.litecommands.requirement.Requirement;

import java.lang.annotation.Annotation;

interface RequirementFactory<A extends Annotation> {

<PARSED> Requirement<PARSED> create(AnnotationHolder<A, PARSED, ?> holder);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package dev.rollczi.litecommands.annotation;

import dev.rollczi.litecommands.annotation.processor.AnnotationInvoker;
import dev.rollczi.litecommands.annotation.processor.AnnotationProcessor;

import java.lang.annotation.Annotation;
import java.util.Optional;

public class RequirementProcessor<SENDER, A extends Annotation> implements AnnotationProcessor<SENDER> {

private final RequirementFactory<A> requirementFactory;
private final Class<A> annotationClass;

public RequirementProcessor(Class<A> annotationClass, ArgumentFactory<A> argumentFactory) {
this.requirementFactory = new ArgumentRequirementFactory<>(argumentFactory);
this.annotationClass = annotationClass;
}

public RequirementProcessor(Class<A> annotationClass) {
this.requirementFactory = new ContextRequirementFactory<>();
this.annotationClass = annotationClass;
}

@Override
public AnnotationInvoker<SENDER> process(AnnotationInvoker<SENDER> invoker) {
return invoker.onRequirement(annotationClass, (holder, builder) -> Optional.of(requirementFactory.create(holder)));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ AnnotationInvoker<SENDER> onRequirement(Class<A> annotationType, AnnotationProce
return this;
}

default <A extends Annotation>
AnnotationInvoker<SENDER> onRequirementMeta(Class<A> annotationType, AnnotationProcessor.RequirementMetaListener<SENDER, A> listener) {
return this;
}

CommandBuilder<SENDER> getResult();

}
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
package dev.rollczi.litecommands.annotation.processor;

import dev.rollczi.litecommands.annotation.AnnotationHolder;
import dev.rollczi.litecommands.command.CommandExecutorProvider;
import dev.rollczi.litecommands.command.builder.CommandBuilder;
import dev.rollczi.litecommands.command.builder.CommandBuilderExecutor;
import dev.rollczi.litecommands.command.executor.CommandExecutorBuilder;
import dev.rollczi.litecommands.meta.MetaHolder;
import dev.rollczi.litecommands.requirement.Requirement;

import java.lang.annotation.Annotation;
import java.util.Optional;

public interface AnnotationProcessor<SENDER> {

Expand All @@ -20,12 +23,15 @@ interface StructureListener<SENDER, A extends Annotation> {
}

interface StructureExecutorListener<SENDER, A extends Annotation> {
CommandBuilder<SENDER> call(A annotation, CommandBuilder<SENDER> builder, CommandBuilderExecutor<SENDER> executorBuilder);
CommandBuilder<SENDER> call(A annotation, CommandBuilder<SENDER> builder, CommandExecutorProvider<SENDER> executorProvider);
}

interface RequirementListener<SENDER, A extends Annotation> {
CommandBuilder<SENDER> call(AnnotationHolder<A, ?, ?> annotationHolder, CommandBuilder<SENDER> builder, CommandBuilderExecutor<SENDER> executorBuilder);
Optional<Requirement<?>> call(AnnotationHolder<A, ?, ?> annotationHolder, CommandBuilder<SENDER> builder);
}

interface RequirementMetaListener<SENDER, A extends Annotation> {
void call(AnnotationHolder<A, ?, ?> annotationHolder, CommandBuilder<SENDER> builder, Requirement<?> requirement);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package dev.rollczi.litecommands.annotation.processor;

import dev.rollczi.litecommands.annotation.RequirementProcessor;
import dev.rollczi.litecommands.argument.Arg;
import dev.rollczi.litecommands.argument.ArgArgumentFactory;
import dev.rollczi.litecommands.async.AsyncAnnotationResolver;
import dev.rollczi.litecommands.command.CommandAnnotationProcessor;
import dev.rollczi.litecommands.command.RootCommandAnnotationProcessor;
import dev.rollczi.litecommands.command.builder.CommandBuilder;
import dev.rollczi.litecommands.execute.ExecuteAnnotationResolver;
import dev.rollczi.litecommands.context.Context;
import dev.rollczi.litecommands.description.DescriptionAnnotationResolver;
import dev.rollczi.litecommands.flag.Flag;
import dev.rollczi.litecommands.flag.FlagArgumentFactory;
import dev.rollczi.litecommands.join.Join;
import dev.rollczi.litecommands.join.JoinArgumentFactory;
import dev.rollczi.litecommands.meta.MarkMetaAnnotationResolver;
import dev.rollczi.litecommands.permission.PermissionAnnotationResolver;
import dev.rollczi.litecommands.permission.PermissionsAnnotationResolver;
import dev.rollczi.litecommands.validator.ValidateAnnotationResolver;

import java.util.ArrayList;
import java.util.List;

public class AnnotationProcessorService<SENDER> {

private final List<AnnotationProcessor<SENDER>> annotationProcessors = new ArrayList<>();

public <A extends AnnotationProcessor<SENDER>> AnnotationProcessorService<SENDER> register(A processor) {
annotationProcessors.add(processor);
return this;
}

public CommandBuilder<SENDER> process(AnnotationInvoker<SENDER> invoker) {
for (AnnotationProcessor<SENDER> processor : annotationProcessors) {
invoker = processor.process(invoker);
}

return invoker.getResult();
}

public static <SENDER> AnnotationProcessorService<SENDER> defaultService() {
return new AnnotationProcessorService<SENDER>()
.register(new CommandAnnotationProcessor<>())
.register(new RootCommandAnnotationProcessor<>())
.register(new MarkMetaAnnotationResolver<>())
.register(new DescriptionAnnotationResolver<>())
.register(new AsyncAnnotationResolver<>())
.register(new PermissionAnnotationResolver<>())
.register(new PermissionsAnnotationResolver<>())
.register(new ValidateAnnotationResolver<>())
.register(new ExecuteAnnotationResolver<>())
.register(new RequirementProcessor<>(Flag.class, new FlagArgumentFactory()))
.register(new RequirementProcessor<>(Arg.class, new ArgArgumentFactory()))
.register(new RequirementProcessor<>(Join.class, new JoinArgumentFactory()))
.register(new RequirementProcessor<>(Context.class));
}

}
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
package dev.rollczi.litecommands.annotations;

import dev.rollczi.litecommands.command.builder.CommandBuilder;
import dev.rollczi.litecommands.command.builder.CommandBuilderExecutor;
import dev.rollczi.litecommands.annotation.processor.AnnotationInvoker;
import dev.rollczi.litecommands.annotation.processor.AnnotationProcessorService;
import dev.rollczi.litecommands.annotation.processor.SourceProcessor;
import dev.rollczi.litecommands.reflect.LiteCommandsReflectException;
import dev.rollczi.litecommands.wrapper.WrapperRegistry;

import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

class InstanceSourceProcessor<SENDER> implements SourceProcessor<SENDER, InstanceSource> {
class InstanceSourceProcessor<SENDER> {

private final AnnotationProcessorService<SENDER> annotationProcessorService;
private final WrapperRegistry wrapperRegistry;
Expand All @@ -24,7 +20,6 @@ public InstanceSourceProcessor(
this.wrapperRegistry = wrapperRegistry;
}

@Override
public CommandBuilder<SENDER> processBuilder(InstanceSource source) {
Object instance = source.getInstance();
Class<?> type = instance.getClass();
Expand All @@ -34,29 +29,9 @@ public CommandBuilder<SENDER> processBuilder(InstanceSource source) {
context = annotationProcessorService.process(classInvoker);

for (Method method : type.getDeclaredMethods()) {
CommandBuilderExecutor<SENDER> executorBuilder = new CommandBuilderExecutor<>(context);
MethodInvoker<SENDER> methodInvoker = new MethodInvoker<>(instance, method, context, executorBuilder);
MethodInvoker<SENDER> methodInvoker = new MethodInvoker<>(annotationProcessorService, wrapperRegistry, instance, method, context);

context = annotationProcessorService.process(methodInvoker);

if (!executorBuilder.buildable()) {
continue;
}

int exceptedParametersCount = 1;
for (Parameter parameter : method.getParameters()) {
AnnotationInvoker<SENDER> parameterInvoker = new ParameterInvoker<>(wrapperRegistry, parameter, context, executorBuilder);

context = annotationProcessorService.process(parameterInvoker);

if (executorBuilder.getRequirementsCount() != exceptedParametersCount) { //TODO może zrobić return value flow?
throw new LiteCommandsReflectException(method, parameter, "Cannot find annotation processor for parameter!");
}

exceptedParametersCount++;
}


}

return context;
Expand Down
Loading

0 comments on commit e161768

Please sign in to comment.