Skip to content

Commit 7f37bf3

Browse files
hugmanriquekashike
authored andcommitted
Consider arguments when literal is impermissible
Fixes Mojang#87
1 parent 447ddfb commit 7f37bf3

File tree

2 files changed

+54
-1
lines changed

2 files changed

+54
-1
lines changed

src/main/java/com/mojang/brigadier/tree/CommandNode.java

+12-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
import com.mojang.brigadier.suggestion.Suggestions;
1616
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
1717

18+
import java.util.ArrayList;
1819
import java.util.Collection;
1920
import java.util.Collections;
2021
import java.util.HashSet;
2122
import java.util.LinkedHashMap;
23+
import java.util.List;
2224
import java.util.Map;
2325
import java.util.Set;
2426
import java.util.TreeMap;
@@ -189,7 +191,16 @@ public Collection<? extends CommandNode<S>> getRelevantNodes(final StringReader
189191
input.setCursor(cursor);
190192
final CommandNode<S> node = children.get(text);
191193
if (node instanceof LiteralCommandNode<?>) {
192-
return Collections.singleton(node);
194+
final int argumentsCount = arguments.size();
195+
if (argumentsCount == 0) {
196+
return Collections.singletonList(node);
197+
} else {
198+
final List<CommandNode<S>> nodes =
199+
new ArrayList<>(argumentsCount + 1);
200+
nodes.add(node); // literals have priority over arguments
201+
nodes.addAll(arguments.values());
202+
return nodes;
203+
}
193204
} else {
194205
return arguments.values();
195206
}

src/test/java/com/mojang/brigadier/CommandDispatcherTest.java

+42
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
package com.mojang.brigadier;
55

66
import com.google.common.collect.Lists;
7+
import com.mojang.brigadier.arguments.StringArgumentType;
78
import com.mojang.brigadier.context.CommandContext;
89
import com.mojang.brigadier.context.CommandContextBuilder;
910
import com.mojang.brigadier.context.StringRange;
@@ -302,6 +303,47 @@ public void testExecuteAmbiguiousParentSubcommandViaRedirect() throws Exception
302303
verify(command, never()).run(any());
303304
}
304305

306+
@SuppressWarnings("unchecked")
307+
@Test
308+
public void testPreferExecuteLiteralOverArguments() throws Exception {
309+
final Command<Object> literalCommand = mock(Command.class);
310+
when(literalCommand.run(any())).thenReturn(100);
311+
312+
subject.register(
313+
literal("test")
314+
.then(
315+
argument("incorrect", StringArgumentType.word())
316+
.executes(command)
317+
)
318+
.then(
319+
literal("hello")
320+
.executes(literalCommand)
321+
)
322+
);
323+
324+
assertThat(subject.execute("test hello", source), is(100));
325+
verify(literalCommand).run(any(CommandContext.class));
326+
verify(command, never()).run(any());
327+
}
328+
329+
@SuppressWarnings("unchecked")
330+
@Test
331+
public void testExecuteAmbiguousArgumentIfImpermissibleLiteral() throws Exception {
332+
subject.register(literal("foo")
333+
.then(
334+
literal("bar")
335+
.requires(source -> false)
336+
)
337+
.then(
338+
argument("argument", StringArgumentType.word())
339+
.executes(command)
340+
)
341+
);
342+
343+
assertThat(subject.execute("foo bar", source), is(42));
344+
verify(command).run(any(CommandContext.class));
345+
}
346+
305347
@SuppressWarnings("unchecked")
306348
@Test
307349
public void testExecuteRedirectedMultipleTimes() throws Exception {

0 commit comments

Comments
 (0)