Split ParsedArgument into fixed or dynamic, added copy methods for caching contexts
This commit is contained in:
parent
3946b084a0
commit
8e3b29d22e
9 changed files with 228 additions and 50 deletions
|
@ -3,6 +3,7 @@ package com.mojang.brigadier.arguments;
|
||||||
import com.google.common.base.Splitter;
|
import com.google.common.base.Splitter;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
import com.mojang.brigadier.context.CommandContext;
|
import com.mojang.brigadier.context.CommandContext;
|
||||||
|
import com.mojang.brigadier.context.FixedParsedArgument;
|
||||||
import com.mojang.brigadier.context.ParsedArgument;
|
import com.mojang.brigadier.context.ParsedArgument;
|
||||||
import com.mojang.brigadier.exceptions.CommandException;
|
import com.mojang.brigadier.exceptions.CommandException;
|
||||||
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
|
import com.mojang.brigadier.exceptions.ParameterizedCommandExceptionType;
|
||||||
|
@ -54,7 +55,7 @@ public class IntegerArgumentType implements CommandArgumentType<Integer> {
|
||||||
throw ERROR_TOO_BIG.create(value, maximum);
|
throw ERROR_TOO_BIG.create(value, maximum);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ParsedArgument<>(raw, value);
|
return new FixedParsedArgument<>(raw, value);
|
||||||
} catch (NumberFormatException ignored) {
|
} catch (NumberFormatException ignored) {
|
||||||
throw ERROR_NOT_A_NUMBER.create(raw);
|
throw ERROR_NOT_A_NUMBER.create(raw);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.mojang.brigadier.context;
|
||||||
|
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
import com.google.common.collect.Iterables;
|
import com.google.common.collect.Iterables;
|
||||||
|
import com.google.common.collect.Maps;
|
||||||
import com.google.common.primitives.Primitives;
|
import com.google.common.primitives.Primitives;
|
||||||
import com.mojang.brigadier.Command;
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.CommandDispatcher;
|
import com.mojang.brigadier.CommandDispatcher;
|
||||||
|
@ -78,4 +79,10 @@ public class CommandContext<S> {
|
||||||
public Map<CommandNode<S>, String> getNodes() {
|
public Map<CommandNode<S>, String> getNodes() {
|
||||||
return nodes;
|
return nodes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public CommandContext<S> copy() {
|
||||||
|
Map<String, ParsedArgument<?>> arguments = Maps.newHashMap();
|
||||||
|
this.arguments.forEach((k, v) -> arguments.put(k, v.copy()));
|
||||||
|
return new CommandContext<>(source, arguments, command, nodes);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
package com.mojang.brigadier.context;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
public class DynamicParsedArgument<T> implements ParsedArgument<T> {
|
||||||
|
private final String raw;
|
||||||
|
private Supplier<T> supplier;
|
||||||
|
private boolean evaluated;
|
||||||
|
private T result;
|
||||||
|
|
||||||
|
public DynamicParsedArgument(String raw, Supplier<T> supplier) {
|
||||||
|
this.raw = raw;
|
||||||
|
this.supplier = supplier;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRaw() {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getResult() {
|
||||||
|
if (!evaluated) {
|
||||||
|
result = supplier.get();
|
||||||
|
evaluated = true;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof DynamicParsedArgument)) return false;
|
||||||
|
|
||||||
|
DynamicParsedArgument that = (DynamicParsedArgument) o;
|
||||||
|
|
||||||
|
if (!raw.equals(that.raw)) return false;
|
||||||
|
if (!supplier.equals(that.supplier)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = raw.hashCode();
|
||||||
|
result = 31 * result + supplier.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParsedArgument<T> copy() {
|
||||||
|
return new DynamicParsedArgument<>(raw, supplier);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,46 @@
|
||||||
|
package com.mojang.brigadier.context;
|
||||||
|
|
||||||
|
public class FixedParsedArgument<T> implements ParsedArgument<T> {
|
||||||
|
private final String raw;
|
||||||
|
private final T result;
|
||||||
|
|
||||||
|
public FixedParsedArgument(String raw, T result) {
|
||||||
|
this.raw = raw;
|
||||||
|
this.result = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRaw() {
|
||||||
|
return raw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public T getResult() {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (!(o instanceof FixedParsedArgument)) return false;
|
||||||
|
|
||||||
|
FixedParsedArgument that = (FixedParsedArgument) o;
|
||||||
|
|
||||||
|
if (!raw.equals(that.raw)) return false;
|
||||||
|
if (!result.equals(that.result)) return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int result = raw.hashCode();
|
||||||
|
result = 31 * result + this.result.hashCode();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ParsedArgument<T> copy() {
|
||||||
|
return new FixedParsedArgument<>(raw, result);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,39 +1,9 @@
|
||||||
package com.mojang.brigadier.context;
|
package com.mojang.brigadier.context;
|
||||||
|
|
||||||
public class ParsedArgument<T> {
|
public interface ParsedArgument<T> {
|
||||||
private final String raw;
|
String getRaw();
|
||||||
private final T result;
|
|
||||||
|
|
||||||
public ParsedArgument(String raw, T result) {
|
T getResult();
|
||||||
this.raw = raw;
|
|
||||||
this.result = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getRaw() {
|
ParsedArgument<T> copy();
|
||||||
return raw;
|
|
||||||
}
|
|
||||||
|
|
||||||
public T getResult() {
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean equals(Object o) {
|
|
||||||
if (this == o) return true;
|
|
||||||
if (!(o instanceof ParsedArgument)) return false;
|
|
||||||
|
|
||||||
ParsedArgument that = (ParsedArgument) o;
|
|
||||||
|
|
||||||
if (!raw.equals(that.raw)) return false;
|
|
||||||
if (!result.equals(that.result)) return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int hashCode() {
|
|
||||||
int result1 = raw.hashCode();
|
|
||||||
result1 = 31 * result1 + result.hashCode();
|
|
||||||
return result1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,17 @@ import org.junit.runner.RunWith;
|
||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.runners.MockitoJUnitRunner;
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
import static com.mojang.brigadier.arguments.IntegerArgumentType.integer;
|
||||||
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
import static com.mojang.brigadier.builder.LiteralArgumentBuilder.literal;
|
||||||
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
import static com.mojang.brigadier.builder.RequiredArgumentBuilder.argument;
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
import static org.hamcrest.Matchers.is;
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.hamcrest.Matchers.not;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
import static org.mockito.Mockito.mock;
|
import static org.mockito.Mockito.mock;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
@RunWith(MockitoJUnitRunner.class)
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
public class CommandContextTest {
|
public class CommandContextTest {
|
||||||
|
@ -74,4 +79,20 @@ public class CommandContextTest {
|
||||||
|
|
||||||
assertThat(context.getInput(), is("foo 100 baz"));
|
assertThat(context.getInput(), is("foo 100 baz"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testCopy() throws Exception {
|
||||||
|
Object first = new Object();
|
||||||
|
Object second = new Object();
|
||||||
|
@SuppressWarnings("unchecked") Supplier<Object> supplier = (Supplier<Object>) mock(Supplier.class);
|
||||||
|
|
||||||
|
when(supplier.get()).thenReturn(first);
|
||||||
|
CommandContext<Object> context = builder.withNode(literal("test").build(), "test").withArgument("test", new DynamicParsedArgument<>("test", supplier)).build();
|
||||||
|
assertThat(context.getArgument("test", Object.class).getResult(), is(first));
|
||||||
|
|
||||||
|
when(supplier.get()).thenReturn(second);
|
||||||
|
CommandContext<Object> copy = context.copy();
|
||||||
|
assertThat(context, is(equalTo(copy)));
|
||||||
|
assertThat(copy.getArgument("test", Object.class).getResult(), is(second));
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,67 @@
|
||||||
|
package com.mojang.brigadier.context;
|
||||||
|
|
||||||
|
import com.google.common.testing.EqualsTester;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
import org.junit.runner.RunWith;
|
||||||
|
import org.mockito.Mock;
|
||||||
|
import org.mockito.runners.MockitoJUnitRunner;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
import static org.mockito.Mockito.times;
|
||||||
|
import static org.mockito.Mockito.verify;
|
||||||
|
import static org.mockito.Mockito.when;
|
||||||
|
|
||||||
|
@RunWith(MockitoJUnitRunner.class)
|
||||||
|
public class DynamicParsedArgumentTest {
|
||||||
|
private DynamicParsedArgument<Object> subject;
|
||||||
|
@Mock
|
||||||
|
private Supplier<Object> supplier;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
subject = new DynamicParsedArgument<>("raw", supplier);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void suppliedOnce() throws Exception {
|
||||||
|
Object result = new Object();
|
||||||
|
when(supplier.get()).thenReturn(result);
|
||||||
|
|
||||||
|
assertThat("first evaluation", subject.getResult(), is(result));
|
||||||
|
assertThat("already evaluated", subject.getResult(), is(result));
|
||||||
|
|
||||||
|
verify(supplier, times(1)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void copy() throws Exception {
|
||||||
|
Object result = new Object();
|
||||||
|
when(supplier.get()).thenReturn(result);
|
||||||
|
assertThat(subject.getResult(), is(result));
|
||||||
|
|
||||||
|
Object newResult = new Object();
|
||||||
|
when(supplier.get()).thenReturn(newResult);
|
||||||
|
ParsedArgument<Object> copy = subject.copy();
|
||||||
|
assertThat(copy.getResult(), is(newResult));
|
||||||
|
|
||||||
|
assertThat(copy, is(equalTo(subject)));
|
||||||
|
|
||||||
|
verify(supplier, times(2)).get();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testEquals() throws Exception {
|
||||||
|
new EqualsTester()
|
||||||
|
.addEqualityGroup(new FixedParsedArgument<>("foo", "bar"), new FixedParsedArgument<>("foo", "bar"))
|
||||||
|
.addEqualityGroup(new FixedParsedArgument<>("bar", "baz"), new FixedParsedArgument<>("bar", "baz"))
|
||||||
|
.addEqualityGroup(new FixedParsedArgument<>("foo", "baz"), new FixedParsedArgument<>("foo", "baz"))
|
||||||
|
.testEquals();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.mojang.brigadier.context;
|
||||||
|
|
||||||
|
import com.google.common.testing.EqualsTester;
|
||||||
|
import org.hamcrest.Matchers;
|
||||||
|
import org.junit.Assert;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.hamcrest.Matchers.equalTo;
|
||||||
|
import static org.hamcrest.Matchers.is;
|
||||||
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
public class FixedParsedArgumentTest {
|
||||||
|
@Test
|
||||||
|
public void testEquals() throws Exception {
|
||||||
|
new EqualsTester()
|
||||||
|
.addEqualityGroup(new FixedParsedArgument<>("foo", "bar"), new FixedParsedArgument<>("foo", "bar"))
|
||||||
|
.addEqualityGroup(new FixedParsedArgument<>("bar", "baz"), new FixedParsedArgument<>("bar", "baz"))
|
||||||
|
.addEqualityGroup(new FixedParsedArgument<>("foo", "baz"), new FixedParsedArgument<>("foo", "baz"))
|
||||||
|
.testEquals();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void copy() throws Exception {
|
||||||
|
final FixedParsedArgument<String> argument = new FixedParsedArgument<>("foo", "bar");
|
||||||
|
assertThat(argument.copy(), is(equalTo(argument)));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +0,0 @@
|
||||||
package com.mojang.brigadier.context;
|
|
||||||
|
|
||||||
import com.google.common.testing.EqualsTester;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
public class ParsedArgumentTest {
|
|
||||||
@Test
|
|
||||||
public void testEquals() throws Exception {
|
|
||||||
new EqualsTester()
|
|
||||||
.addEqualityGroup(new ParsedArgument<>("foo", "bar"), new ParsedArgument<>("foo", "bar"))
|
|
||||||
.addEqualityGroup(new ParsedArgument<>("bar", "baz"), new ParsedArgument<>("bar", "baz"))
|
|
||||||
.addEqualityGroup(new ParsedArgument<>("foo", "baz"), new ParsedArgument<>("foo", "baz"))
|
|
||||||
.testEquals();
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in a new issue