Store the currently parsing argument in the command context

This fixes #101
This commit is contained in:
Alexander Söderberg 2020-10-25 05:51:39 +01:00 committed by Alexander Söderberg
parent c2065aabd1
commit d484b99fc4
3 changed files with 37 additions and 0 deletions

View file

@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
### Added ### Added
- Added access to the CloudBrigadierManager from Brigadier-enabled command managers - Added access to the CloudBrigadierManager from Brigadier-enabled command managers
- Added parameter injectors - Added parameter injectors
- Store currently parsing command argument in the command context
## [1.1.0] - 2020-10-24 ## [1.1.0] - 2020-10-24

View file

@ -209,6 +209,7 @@ public final class CommandTree<C> {
final CommandContext.ArgumentTiming argumentTiming = commandContext.createTiming(argument); final CommandContext.ArgumentTiming argumentTiming = commandContext.createTiming(argument);
argumentTiming.setStart(System.nanoTime()); argumentTiming.setStart(System.nanoTime());
commandContext.setCurrentArgument(argument);
final ArgumentParseResult<?> result = argument.getParser().parse(commandContext, commandQueue); final ArgumentParseResult<?> result = argument.getParser().parse(commandContext, commandQueue);
argumentTiming.setEnd(System.nanoTime(), result.getFailure().isPresent()); argumentTiming.setEnd(System.nanoTime(), result.getFailure().isPresent());
@ -377,6 +378,7 @@ public final class CommandTree<C> {
commandQueue commandQueue
); );
if (!preParseResult.getFailure().isPresent() && preParseResult.getParsedValue().orElse(false)) { if (!preParseResult.getFailure().isPresent() && preParseResult.getParsedValue().orElse(false)) {
commandContext.setCurrentArgument(argument);
result = argument.getParser().parse(commandContext, commandQueue); result = argument.getParser().parse(commandContext, commandQueue);
} else { } else {
result = preParseResult; result = preParseResult;
@ -489,14 +491,17 @@ public final class CommandTree<C> {
if (commandQueue.isEmpty()) { if (commandQueue.isEmpty()) {
return Collections.emptyList(); return Collections.emptyList();
} else if (child.isLeaf() && commandQueue.size() < 2) { } else if (child.isLeaf() && commandQueue.size() < 2) {
commandContext.setCurrentArgument(child.getValue());
return child.getValue().getSuggestionsProvider().apply(commandContext, commandQueue.peek()); return child.getValue().getSuggestionsProvider().apply(commandContext, commandQueue.peek());
} else if (child.isLeaf()) { } else if (child.isLeaf()) {
if (child.getValue() instanceof CompoundArgument) { if (child.getValue() instanceof CompoundArgument) {
final String last = ((LinkedList<String>) commandQueue).getLast(); final String last = ((LinkedList<String>) commandQueue).getLast();
commandContext.setCurrentArgument(child.getValue());
return child.getValue().getSuggestionsProvider().apply(commandContext, last); return child.getValue().getSuggestionsProvider().apply(commandContext, last);
} }
return Collections.emptyList(); return Collections.emptyList();
} else if (commandQueue.peek().isEmpty()) { } else if (commandQueue.peek().isEmpty()) {
commandContext.setCurrentArgument(child.getValue());
return child.getValue().getSuggestionsProvider().apply(commandContext, commandQueue.remove()); return child.getValue().getSuggestionsProvider().apply(commandContext, commandQueue.remove());
} }
@ -507,17 +512,20 @@ public final class CommandTree<C> {
); );
if (preParseResult.getFailure().isPresent() || !preParseResult.getParsedValue().orElse(false)) { if (preParseResult.getFailure().isPresent() || !preParseResult.getParsedValue().orElse(false)) {
final String value = commandQueue.peek() == null ? "" : commandQueue.peek(); final String value = commandQueue.peek() == null ? "" : commandQueue.peek();
commandContext.setCurrentArgument(child.getValue());
return child.getValue().getSuggestionsProvider().apply(commandContext, value); return child.getValue().getSuggestionsProvider().apply(commandContext, value);
} }
// END: Preprocessing // END: Preprocessing
// START: Parsing // START: Parsing
commandContext.setCurrentArgument(child.getValue());
final ArgumentParseResult<?> result = child.getValue().getParser().parse(commandContext, commandQueue); final ArgumentParseResult<?> result = child.getValue().getParser().parse(commandContext, commandQueue);
if (result.getParsedValue().isPresent()) { if (result.getParsedValue().isPresent()) {
commandContext.store(child.getValue().getName(), result.getParsedValue().get()); commandContext.store(child.getValue().getName(), result.getParsedValue().get());
return this.getSuggestions(commandContext, commandQueue, child); return this.getSuggestions(commandContext, commandQueue, child);
} else if (result.getFailure().isPresent()) { } else if (result.getFailure().isPresent()) {
final String value = commandQueue.peek() == null ? "" : commandQueue.peek(); final String value = commandQueue.peek() == null ? "" : commandQueue.peek();
commandContext.setCurrentArgument(child.getValue());
return child.getValue().getSuggestionsProvider().apply(commandContext, value); return child.getValue().getSuggestionsProvider().apply(commandContext, value);
} }
// END: Parsing // END: Parsing
@ -532,6 +540,7 @@ public final class CommandTree<C> {
while (childIterator.hasNext()) { while (childIterator.hasNext()) {
final Node<CommandArgument<C, ?>> child = childIterator.next(); final Node<CommandArgument<C, ?>> child = childIterator.next();
if (child.getValue() != null) { if (child.getValue() != null) {
commandContext.setCurrentArgument(child.getValue());
final ArgumentParseResult<?> result = child.getValue().getParser().parse( final ArgumentParseResult<?> result = child.getValue().getParser().parse(
commandContext, commandContext,
commandQueue commandQueue
@ -555,6 +564,7 @@ public final class CommandTree<C> {
if (argument.getValue() == null || this.isPermitted(commandContext.getSender(), argument) != null) { if (argument.getValue() == null || this.isPermitted(commandContext.getSender(), argument) != null) {
continue; continue;
} }
commandContext.setCurrentArgument(argument.getValue());
final List<String> suggestionsToAdd = argument.getValue().getSuggestionsProvider() final List<String> suggestionsToAdd = argument.getValue().getSuggestionsProvider()
.apply(commandContext, stringOrEmpty(commandQueue.peek())); .apply(commandContext, stringOrEmpty(commandQueue.peek()));
suggestions.addAll(suggestionsToAdd); suggestions.addAll(suggestionsToAdd);

View file

@ -55,6 +55,8 @@ public final class CommandContext<C> {
private final boolean suggestions; private final boolean suggestions;
private final CaptionRegistry<C> captionRegistry; private final CaptionRegistry<C> captionRegistry;
private CommandArgument<C, ?> currentArgument = null;
/** /**
* Create a new command context instance * Create a new command context instance
* *
@ -285,6 +287,30 @@ public final class CommandContext<C> {
return this.flagContext; return this.flagContext;
} }
/**
* Get the argument that is currently being parsed for this command context.
* This value will be updated whenever the context is used to provide new
* suggestions or parse a new command argument
*
* @return Currently parsing {@link CommandArgument} or {@code null}
* @since 1.2.0
*/
public @Nullable CommandArgument<C, ?> getCurrentArgument() {
return this.currentArgument;
}
/**
* Set the argument that is currently being parsed for this command context.
* This value should be updated whenever the context is used to provide new
* suggestions or parse a new command argument
*
* @param argument Currently parsing {@link CommandArgument} or {@code null}
* @since 1.2.0
*/
public void setCurrentArgument(final @Nullable CommandArgument<C, ?> argument) {
this.currentArgument = argument;
}
/** /**
* Used to track performance metrics related to command parsing. This is attached * Used to track performance metrics related to command parsing. This is attached