Consider arguments when literal is impermissible
Fixes https://github.com/Mojang/brigadier/issues/87
This commit is contained in:
parent
cf754c4ef6
commit
901d6bf0ca
2 changed files with 52 additions and 1 deletions
|
@ -14,6 +14,7 @@ import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
|||
import com.mojang.brigadier.suggestion.Suggestions;
|
||||
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
|
@ -160,7 +161,15 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
|
|||
input.setCursor(cursor);
|
||||
final LiteralCommandNode<S> literal = literals.get(text);
|
||||
if (literal != null) {
|
||||
return Collections.singleton(literal);
|
||||
final int argumentsCount = arguments.size();
|
||||
if (argumentsCount == 0) {
|
||||
return Collections.singletonList(literal);
|
||||
} else {
|
||||
final Collection<CommandNode<S>> nodes = new ArrayList<>(argumentsCount + 1);
|
||||
nodes.add(literal); // literals have priority over arguments
|
||||
nodes.addAll(arguments.values());
|
||||
return nodes;
|
||||
}
|
||||
} else {
|
||||
return arguments.values();
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
package com.mojang.brigadier;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.mojang.brigadier.arguments.StringArgumentType;
|
||||
import com.mojang.brigadier.context.CommandContext;
|
||||
import com.mojang.brigadier.context.CommandContextBuilder;
|
||||
import com.mojang.brigadier.exceptions.CommandSyntaxException;
|
||||
|
@ -256,6 +257,47 @@ public class CommandDispatcherTest {
|
|||
verify(command, never()).run(any());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testPreferExecuteLiteralOverArguments() throws Exception {
|
||||
final Command<Object> literalCommand = mock(Command.class);
|
||||
when(literalCommand.run(any())).thenReturn(100);
|
||||
|
||||
subject.register(
|
||||
literal("test")
|
||||
.then(
|
||||
argument("incorrect", StringArgumentType.word())
|
||||
.executes(command)
|
||||
)
|
||||
.then(
|
||||
literal("hello")
|
||||
.executes(literalCommand)
|
||||
)
|
||||
);
|
||||
|
||||
assertThat(subject.execute("test hello", source), is(100));
|
||||
verify(literalCommand).run(any(CommandContext.class));
|
||||
verify(command, never()).run(any());
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testExecuteAmbiguousArgumentIfImpermissibleLiteral() throws Exception {
|
||||
subject.register(literal("foo")
|
||||
.then(
|
||||
literal("bar")
|
||||
.requires(source -> false)
|
||||
)
|
||||
.then(
|
||||
argument("argument", StringArgumentType.word())
|
||||
.executes(command)
|
||||
)
|
||||
);
|
||||
|
||||
assertThat(subject.execute("foo bar", source), is(42));
|
||||
verify(command).run(any(CommandContext.class));
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@Test
|
||||
public void testExecuteRedirectedMultipleTimes() throws Exception {
|
||||
|
|
Loading…
Reference in a new issue