Skip to content
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,7 @@ gradle-app.setting
hs_err_pid*


repo/
repo/

# vscode workspace settings
.vscode
4 changes: 2 additions & 2 deletions src/main/java/com/mojang/brigadier/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@
import com.mojang.brigadier.exceptions.CommandSyntaxException;

@FunctionalInterface
public interface Command<S> {
public interface Command<S, R> {
int SINGLE_SUCCESS = 1;

int run(CommandContext<S> context) throws CommandSyntaxException;
R run(CommandContext<S> context) throws CommandSyntaxException;
}
27 changes: 15 additions & 12 deletions src/main/java/com/mojang/brigadier/CommandDispatcher.java
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Copyright (c) Microsoft Corporation and Serena Lynas. All rights reserved.
// Licensed under the MIT license.

package com.mojang.brigadier;
Expand All @@ -8,6 +8,9 @@
import com.mojang.brigadier.context.CommandContextBuilder;
import com.mojang.brigadier.context.SuggestionContext;
import com.mojang.brigadier.exceptions.CommandSyntaxException;
import com.mojang.brigadier.results.CommandResult;
import com.mojang.brigadier.results.EmptyCommandResult;
import com.mojang.brigadier.results.ListCommandResult;
import com.mojang.brigadier.suggestion.Suggestions;
import com.mojang.brigadier.suggestion.SuggestionsBuilder;
import com.mojang.brigadier.tree.CommandNode;
Expand Down Expand Up @@ -62,7 +65,7 @@ public boolean test(final CommandNode<S> input) {
return input != null && (input.getCommand() != null || input.getChildren().stream().anyMatch(hasCommand));
}
};
private ResultConsumer<S> consumer = (c, s, r) -> {
private ResultConsumer<S, Object> consumer = (c, s, r) -> {
};

/**
Expand Down Expand Up @@ -104,7 +107,7 @@ public LiteralCommandNode<S> register(final LiteralArgumentBuilder<S> command) {
*
* @param consumer the new result consumer to be called
*/
public void setConsumer(final ResultConsumer<S> consumer) {
public void setConsumer(final ResultConsumer<S, Object> consumer) {
this.consumer = consumer;
}

Expand Down Expand Up @@ -138,7 +141,7 @@ public void setConsumer(final ResultConsumer<S> consumer) {
* @see #execute(ParseResults)
* @see #execute(StringReader, Object)
*/
public int execute(final String input, final S source) throws CommandSyntaxException {
public Object execute(final String input, final S source) throws CommandSyntaxException {
return execute(new StringReader(input), source);
}

Expand Down Expand Up @@ -172,7 +175,7 @@ public int execute(final String input, final S source) throws CommandSyntaxExcep
* @see #execute(ParseResults)
* @see #execute(String, Object)
*/
public int execute(final StringReader input, final S source) throws CommandSyntaxException {
public Object execute(final StringReader input, final S source) throws CommandSyntaxException {
final ParseResults<S> parse = parse(input, source);
return execute(parse);
}
Expand Down Expand Up @@ -203,7 +206,7 @@ public int execute(final StringReader input, final S source) throws CommandSynta
* @see #execute(String, Object)
* @see #execute(StringReader, Object)
*/
public int execute(final ParseResults<S> parse) throws CommandSyntaxException {
public Object execute(final ParseResults<S> parse) throws CommandSyntaxException {
if (parse.getReader().canRead()) {
if (parse.getExceptions().size() == 1) {
throw parse.getExceptions().values().iterator().next();
Expand All @@ -214,7 +217,7 @@ public int execute(final ParseResults<S> parse) throws CommandSyntaxException {
}
}

int result = 0;
Object result = new EmptyCommandResult();
int successfulForks = 0;
boolean forked = false;
boolean foundCommand = false;
Expand Down Expand Up @@ -250,7 +253,7 @@ public int execute(final ParseResults<S> parse) throws CommandSyntaxException {
}
}
} catch (final CommandSyntaxException ex) {
consumer.onCommandComplete(context, false, 0);
consumer.onCommandComplete(context, false, new EmptyCommandResult());
if (!forked) {
throw ex;
}
Expand All @@ -260,12 +263,12 @@ public int execute(final ParseResults<S> parse) throws CommandSyntaxException {
} else if (context.getCommand() != null) {
foundCommand = true;
try {
final int value = context.getCommand().run(context);
result += value;
final Object value = context.getCommand().run(context);
consumer.onCommandComplete(context, true, value);
result = CommandResult.combine(result, value);
successfulForks++;
} catch (final CommandSyntaxException ex) {
consumer.onCommandComplete(context, false, 0);
consumer.onCommandComplete(context, false, new EmptyCommandResult());
if (!forked) {
throw ex;
}
Expand All @@ -278,7 +281,7 @@ public int execute(final ParseResults<S> parse) throws CommandSyntaxException {
}

if (!foundCommand) {
consumer.onCommandComplete(original, false, 0);
consumer.onCommandComplete(original, false, new EmptyCommandResult());
throw CommandSyntaxException.BUILT_IN_EXCEPTIONS.dispatcherUnknownCommand().createWithContext(parse.getReader());
}

Expand Down
4 changes: 2 additions & 2 deletions src/main/java/com/mojang/brigadier/ResultConsumer.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
import com.mojang.brigadier.context.CommandContext;

@FunctionalInterface
public interface ResultConsumer<S> {
void onCommandComplete(CommandContext<S> context, boolean success, int result);
public interface ResultConsumer<S, R> {
void onCommandComplete(CommandContext<S> context, boolean success, R result);
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

public abstract class ArgumentBuilder<S, T extends ArgumentBuilder<S, T>> {
private final RootCommandNode<S> arguments = new RootCommandNode<>();
private Command<S> command;
private Command<S, ?> command;
private Predicate<S> requirement = s -> true;
private CommandNode<S> target;
private RedirectModifier<S> modifier = null;
Expand Down Expand Up @@ -43,12 +43,12 @@ public Collection<CommandNode<S>> getArguments() {
return arguments.getChildren();
}

public T executes(final Command<S> command) {
public <R> T executes(final Command<S, R> command) {
this.command = command;
return getThis();
}

public Command<S> getCommand() {
public Command<S, ?> getCommand() {
return command;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class CommandContext<S> {

private final S source;
private final String input;
private final Command<S> command;
private final Command<S, ?> command;
private final Map<String, ParsedArgument<S, ?>> arguments;
private final CommandNode<S> rootNode;
private final List<ParsedCommandNode<S>> nodes;
Expand All @@ -37,7 +37,7 @@ public class CommandContext<S> {
private final RedirectModifier<S> modifier;
private final boolean forks;

public CommandContext(final S source, final String input, final Map<String, ParsedArgument<S, ?>> arguments, final Command<S> command, final CommandNode<S> rootNode, final List<ParsedCommandNode<S>> nodes, final StringRange range, final CommandContext<S> child, final RedirectModifier<S> modifier, boolean forks) {
public CommandContext(final S source, final String input, final Map<String, ParsedArgument<S, ?>> arguments, final Command<S, ?> command, final CommandNode<S> rootNode, final List<ParsedCommandNode<S>> nodes, final StringRange range, final CommandContext<S> child, final RedirectModifier<S> modifier, boolean forks) {
this.source = source;
this.input = input;
this.arguments = arguments;
Expand Down Expand Up @@ -69,7 +69,7 @@ public CommandContext<S> getLastChild() {
return result;
}

public Command<S> getCommand() {
public Command<S, ?> getCommand() {
return command;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class CommandContextBuilder<S> {
private final List<ParsedCommandNode<S>> nodes = new ArrayList<>();
private final CommandDispatcher<S> dispatcher;
private S source;
private Command<S> command;
private Command<S, ?> command;
private CommandContextBuilder<S> child;
private StringRange range;
private RedirectModifier<S> modifier = null;
Expand Down Expand Up @@ -54,7 +54,7 @@ public CommandContextBuilder<S> withArgument(final String name, final ParsedArgu
return arguments;
}

public CommandContextBuilder<S> withCommand(final Command<S> command) {
public CommandContextBuilder<S> withCommand(final Command<S, ?> command) {
this.command = command;
return this;
}
Expand Down Expand Up @@ -95,7 +95,7 @@ public CommandContextBuilder<S> getLastChild() {
return result;
}

public Command<S> getCommand() {
public Command<S, ?> getCommand() {
return command;
}

Expand Down
39 changes: 39 additions & 0 deletions src/main/java/com/mojang/brigadier/results/CommandResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
// Copyright (c) Serena Lynas. All rights reserved.
// Licensed under the MIT license.

package com.mojang.brigadier.results;

/**
* Optional interface for CommandResult
*
* Not all things returned from commands
* must implement this interface.
*/
public interface CommandResult {
/**
* Combine one command result with another, returning
* the combined result.
* @param other The other result to combine this result
* with.
* @return The combined result
*/
default Object combine(Object other) {
ListCommandResult list = new ListCommandResult();
list.combine(this);
list.combine(other);
return list;
}

static Object combine(Object target, Object source) {
if (target instanceof CommandResult) {
return ((CommandResult)target).combine(source);
} else if (target instanceof Integer && source instanceof Integer) {
// Backwards compatability
return (Integer)target + (Integer)source;
} else if (source instanceof EmptyCommandResult) {
return target;
} else {
return source;
}
}
}
19 changes: 19 additions & 0 deletions src/main/java/com/mojang/brigadier/results/EmptyCommandResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (c) Serena Lynas. All rights reserved.
// Licensed under the MIT license.

package com.mojang.brigadier.results;

/**
* Empty class which semantically represents
* an empty command result.
*/
public class EmptyCommandResult implements CommandResult {
/**
* Combines this result with another. Always overwrites
* the empty result.
*/
@Override
public Object combine(Object other) {
return other;
}
}
24 changes: 24 additions & 0 deletions src/main/java/com/mojang/brigadier/results/ListCommandResult.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright (c) Serena Lynas. All rights reserved.
// Licensed under the MIT license.

package com.mojang.brigadier.results;

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

public class ListCommandResult implements CommandResult {
private List<Object> results = new ArrayList<>();

public List<Object> getResults() {
return results;
}

@Override
public ListCommandResult combine(Object other) {
if (!(other instanceof EmptyCommandResult)) {
results.add(other);
}

return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public class ArgumentCommandNode<S, T> extends CommandNode<S> {
private final ArgumentType<T> type;
private final SuggestionProvider<S> customSuggestions;

public ArgumentCommandNode(final String name, final ArgumentType<T> type, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks, final SuggestionProvider<S> customSuggestions) {
public ArgumentCommandNode(final String name, final ArgumentType<T> type, final Command<S, ?> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks, final SuggestionProvider<S> customSuggestions) {
super(command, requirement, redirect, modifier, forks);
this.name = name;
this.type = type;
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/com/mojang/brigadier/tree/CommandNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,17 @@ public abstract class CommandNode<S> implements Comparable<CommandNode<S>> {
private final CommandNode<S> redirect;
private final RedirectModifier<S> modifier;
private final boolean forks;
private Command<S> command;
private Command<S, ?> command;

protected CommandNode(final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
protected CommandNode(final Command<S, ?> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
this.command = command;
this.requirement = requirement;
this.redirect = redirect;
this.modifier = modifier;
this.forks = forks;
}

public Command<S> getCommand() {
public Command<S, ?> getCommand() {
return command;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class LiteralCommandNode<S> extends CommandNode<S> {
private final String literal;
private final String literalLowerCase;

public LiteralCommandNode(final String literal, final Command<S> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
public LiteralCommandNode(final String literal, final Command<S, ?> command, final Predicate<S> requirement, final CommandNode<S> redirect, final RedirectModifier<S> modifier, final boolean forks) {
super(command, requirement, redirect, modifier, forks);
this.literal = literal;
this.literalLowerCase = literal.toLowerCase(Locale.ROOT);
Expand Down
10 changes: 5 additions & 5 deletions src/test/java/com/mojang/brigadier/CommandDispatcherTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
public class CommandDispatcherTest {
private CommandDispatcher<Object> subject;
@Mock
private Command<Object> command;
private Command<Object, Integer> command;
@Mock
private Object source;

Expand Down Expand Up @@ -167,7 +167,7 @@ public void testExecuteAmbiguousIncorrectArgument() throws Exception {
@SuppressWarnings("unchecked")
@Test
public void testExecuteSubcommand() throws Exception {
final Command<Object> subCommand = mock(Command.class);
final Command<Object, Integer> subCommand = mock(Command.class);
when(subCommand.run(any())).thenReturn(100);

subject.register(literal("foo").then(
Expand Down Expand Up @@ -205,7 +205,7 @@ public void testParseIncompleteArgument() throws Exception {
@SuppressWarnings("unchecked")
@Test
public void testExecuteAmbiguiousParentSubcommand() throws Exception {
final Command<Object> subCommand = mock(Command.class);
final Command<Object, Integer> subCommand = mock(Command.class);
when(subCommand.run(any())).thenReturn(100);

subject.register(
Expand All @@ -231,7 +231,7 @@ public void testExecuteAmbiguiousParentSubcommand() throws Exception {
@SuppressWarnings("unchecked")
@Test
public void testExecuteAmbiguiousParentSubcommandViaRedirect() throws Exception {
final Command<Object> subCommand = mock(Command.class);
final Command<Object, Integer> subCommand = mock(Command.class);
when(subCommand.run(any())).thenReturn(100);

final LiteralCommandNode<Object> real = subject.register(
Expand Down Expand Up @@ -343,7 +343,7 @@ public void testExecuteOrphanedSubcommand() throws Exception {

@Test
public void testExecute_invalidOther() throws Exception {
final Command<Object> wrongCommand = mock(Command.class);
final Command<Object, Integer> wrongCommand = mock(Command.class);
subject.register(literal("w").executes(wrongCommand));
subject.register(literal("world").executes(command));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ public class CommandDispatcherUsagesTest {
@Mock
private Object source;
@Mock
private Command<Object> command;
private Command<Object, Integer> command;

@Before
public void setUp() throws Exception {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class LiteralArgumentBuilderTest {
private LiteralArgumentBuilder<Object> builder;
@Mock
private
Command<Object> command;
Command<Object, Integer> command;

@Before
public void setUp() throws Exception {
Expand Down
Loading