Keep nodes sorted alphabetically for niceness

This commit is contained in:
Nathan Adams 2017-07-20 13:32:12 +02:00
parent daea2d76d7
commit eaf4c6175d
10 changed files with 97 additions and 14 deletions

View file

@ -9,5 +9,13 @@ import java.util.Set;
public interface ArgumentType<T> {
<S> ParsedArgument<S, T> parse(String command, CommandContextBuilder<S> contextBuilder) throws CommandException;
<S> void listSuggestions(String command, Set<String> output, CommandContextBuilder<S> contextBuilder);
default <S> void listSuggestions(String command, Set<String> output, CommandContextBuilder<S> contextBuilder) {}
default String getUsageSuffix() {
return null;
}
default String getUsageText() {
return null;
}
}

View file

@ -83,10 +83,6 @@ public class IntegerArgumentType implements ArgumentType<Integer> {
}
}
@Override
public <S> void listSuggestions(String command, Set<String> output, CommandContextBuilder<S> contextBuilder) {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
@ -111,4 +107,14 @@ public class IntegerArgumentType implements ArgumentType<Integer> {
return "integer(" + minimum + ", " + maximum + ")";
}
}
@Override
public String getUsageSuffix() {
return suffix.length() == 0 ? null : suffix;
}
@Override
public String getUsageText() {
return "int";
}
}

View file

@ -96,10 +96,6 @@ public class StringArgumentType implements ArgumentType<String> {
}
}
@Override
public <S> void listSuggestions(String command, Set<String> output, CommandContextBuilder<S> contextBuilder) {
}
@Override
public String toString() {
return "string()";

View file

@ -38,7 +38,15 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
@Override
public String getUsageText() {
return USAGE_ARGUMENT_OPEN + name + USAGE_ARGUMENT_CLOSE;
String usage = name;
if (type.getUsageText() != null) {
usage += ": " + type.getUsageText();
}
usage = USAGE_ARGUMENT_OPEN + usage + USAGE_ARGUMENT_CLOSE;
if (type.getUsageSuffix() != null) {
usage += type.getUsageSuffix();
}
return usage;
}
@Override
@ -89,4 +97,9 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
result = 31 * result + type.hashCode();
return result;
}
@Override
protected String getSortedKey() {
return name;
}
}

View file

@ -1,5 +1,6 @@
package com.mojang.brigadier.tree;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.Maps;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.builder.ArgumentBuilder;
@ -7,12 +8,14 @@ import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandException;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.Predicate;
import java.util.stream.Collectors;
public abstract class CommandNode<S> {
private final Map<Object, CommandNode<S>> children = Maps.newLinkedHashMap();
public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
private Map<Object, CommandNode<S>> children = Maps.newLinkedHashMap();
private Command<S> command;
private Predicate<S> requirement;
@ -46,6 +49,8 @@ public abstract class CommandNode<S> {
} else {
children.put(node.getMergeKey(), node);
}
children = children.entrySet().stream().sorted(Map.Entry.comparingByValue()).collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue, (e1, e2) -> e1, LinkedHashMap::new));
}
@Override
@ -79,4 +84,15 @@ public abstract class CommandNode<S> {
public abstract void listSuggestions(String command, Set<String> output, CommandContextBuilder<S> contextBuilder);
public abstract ArgumentBuilder<S, ?> createBuilder();
protected abstract String getSortedKey();
@Override
public int compareTo(CommandNode<S> o) {
return ComparisonChain
.start()
.compareTrueFirst(this instanceof LiteralCommandNode, o instanceof LiteralCommandNode)
.compare(getSortedKey(), o.getSortedKey())
.result();
}
}

View file

@ -81,4 +81,9 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
}
return builder;
}
@Override
protected String getSortedKey() {
return literal;
}
}

View file

@ -41,4 +41,9 @@ public class RootCommandNode<S> extends CommandNode<S> {
public ArgumentBuilder<S, ?> createBuilder() {
throw new IllegalStateException("Cannot convert root into a builder");
}
@Override
protected String getSortedKey() {
return "";
}
}

View file

@ -36,7 +36,7 @@ public class CommandDispatcherCompletionsTest {
subject.register(literal("foo"));
subject.register(literal("bar"));
subject.register(literal("baz").requires(s -> false));
assertThat(subject.getCompletionSuggestions("", source), equalTo(new String[] {"foo", "bar"}));
assertThat(subject.getCompletionSuggestions("", source), equalTo(new String[] {"bar", "foo"}));
assertThat(subject.getCompletionSuggestions("f", source), equalTo(new String[] {"foo"}));
assertThat(subject.getCompletionSuggestions("b", source), equalTo(new String[] {"bar"}));
assertThat(subject.getCompletionSuggestions("q", source), is(emptyArray()));
@ -46,7 +46,7 @@ public class CommandDispatcherCompletionsTest {
public void testSubCommand() throws Exception {
subject.register(literal("foo").then(literal("abc")).then(literal("def")).then(literal("ghi").requires(s -> false)));
subject.register(literal("bar"));
assertThat(subject.getCompletionSuggestions("", source), equalTo(new String[] {"foo", "bar"}));
assertThat(subject.getCompletionSuggestions("", source), equalTo(new String[] {"bar", "foo"}));
assertThat(subject.getCompletionSuggestions("f", source), equalTo(new String[] {"foo"}));
assertThat(subject.getCompletionSuggestions("foo", source), equalTo(new String[] {"foo"}));
assertThat(subject.getCompletionSuggestions("foo ", source), equalTo(new String[] {"abc", "def"}));

View file

@ -19,6 +19,7 @@ import java.util.Set;
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
import static org.hamcrest.Matchers.empty;
import static org.hamcrest.Matchers.equalTo;
import static org.hamcrest.Matchers.hasToString;
import static org.hamcrest.Matchers.is;
import static org.junit.Assert.assertThat;
@ -202,4 +203,24 @@ public class IntegerArgumentTypeTest {
assertThat(integer(-100, 100), hasToString("integer(-100, 100)"));
assertThat(integer(Integer.MIN_VALUE, 100), hasToString("integer(-2147483648, 100)"));
}
@Test
public void testUsageSuffix() throws Exception {
assertThat(integer().getUsageSuffix(), equalTo(null));
}
@Test
public void testUsageSuffix_suffix() throws Exception {
assertThat(integer(0, 100, "L").getUsageSuffix(), equalTo("L"));
}
@Test
public void testUsageText() throws Exception {
assertThat(integer().getUsageText(), equalTo("int"));
}
@Test
public void testUsageText_suffix() throws Exception {
assertThat(integer(0, 100, "L").getUsageText(), equalTo("int"));
}
}

View file

@ -6,6 +6,7 @@ import com.google.common.testing.EqualsTester;
import com.mojang.brigadier.Command;
import com.mojang.brigadier.CommandDispatcher;
import com.mojang.brigadier.arguments.IntegerArgumentType;
import com.mojang.brigadier.arguments.StringArgumentType;
import com.mojang.brigadier.builder.RequiredArgumentBuilder;
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.exceptions.CommandException;
@ -68,6 +69,18 @@ public class ArgumentCommandNodeTest extends AbstractCommandNodeTest {
@Test
public void testUsage() throws Exception {
assertThat(node.getUsageText(), is("<foo: int>"));
}
@Test
public void testUsage_suffix() throws Exception {
node = argument("foo", integer(0, 100, "L")).build();
assertThat(node.getUsageText(), is("<foo: int>L"));
}
@Test
public void testUsage_empty() throws Exception {
ArgumentCommandNode<Object, String> node = argument("foo", StringArgumentType.word()).build();
assertThat(node.getUsageText(), is("<foo>"));
}