Don't consume optional arguments
This commit is contained in:
parent
916bca59ba
commit
81a76dfd30
@ -69,9 +69,7 @@ import com.sk89q.worldedit.session.request.Request;
|
|||||||
import com.sk89q.worldedit.util.command.SimpleCommandMapping;
|
import com.sk89q.worldedit.util.command.SimpleCommandMapping;
|
||||||
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
import com.sk89q.worldedit.util.command.SimpleDispatcher;
|
||||||
import com.sk89q.worldedit.util.command.fluent.DispatcherNode;
|
import com.sk89q.worldedit.util.command.fluent.DispatcherNode;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParameterData;
|
import com.sk89q.worldedit.util.command.parametric.*;
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParametricBuilder;
|
|
||||||
import com.sk89q.worldedit.util.command.parametric.ParametricCallable;
|
|
||||||
import com.sk89q.worldedit.util.formatting.Fragment;
|
import com.sk89q.worldedit.util.formatting.Fragment;
|
||||||
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
import com.sk89q.worldedit.util.formatting.component.CommandListBox;
|
||||||
import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
|
import com.sk89q.worldedit.util.formatting.component.CommandUsageBox;
|
||||||
@ -449,6 +447,9 @@ public class Fawe {
|
|||||||
Request.inject(); // Custom pattern extent
|
Request.inject(); // Custom pattern extent
|
||||||
// Commands
|
// Commands
|
||||||
Commands.load(new File(INSTANCE.IMP.getDirectory(), "commands.yml"));
|
Commands.load(new File(INSTANCE.IMP.getDirectory(), "commands.yml"));
|
||||||
|
ArgumentStack.inject0(); // Mark/reset
|
||||||
|
ContextArgumentStack.inject();
|
||||||
|
StringArgumentStack.inject();
|
||||||
Commands.inject(); // Translations
|
Commands.inject(); // Translations
|
||||||
BiomeCommands.inject(); // Translations + Optimizations
|
BiomeCommands.inject(); // Translations + Optimizations
|
||||||
ChunkCommands.inject(); // Translations + Optimizations
|
ChunkCommands.inject(); // Translations + Optimizations
|
||||||
|
@ -70,9 +70,11 @@ public class FawePrimitiveBinding extends BindingHelper {
|
|||||||
}
|
}
|
||||||
@BindingMatch(
|
@BindingMatch(
|
||||||
type = {BufferedImage.class},
|
type = {BufferedImage.class},
|
||||||
behavior = BindingBehavior.CONSUMES
|
behavior = BindingBehavior.CONSUMES,
|
||||||
|
consumedCount = 1,
|
||||||
|
provideModifiers = true
|
||||||
)
|
)
|
||||||
public BufferedImage getImage(ArgumentStack context) throws ParameterException {
|
public BufferedImage getImage(ArgumentStack context, Annotation[] modifiers) throws ParameterException {
|
||||||
return ImageUtil.getImage(context.next());
|
return ImageUtil.getImage(context.next());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,98 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util.command.parametric;
|
||||||
|
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
|
|
||||||
|
public interface ArgumentStack {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next string, which may come from the stack or a value flag.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
* @throws ParameterException on a parameter error
|
||||||
|
*/
|
||||||
|
String next() throws ParameterException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next integer, which may come from the stack or a value flag.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
* @throws ParameterException on a parameter error
|
||||||
|
*/
|
||||||
|
Integer nextInt() throws ParameterException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next double, which may come from the stack or a value flag.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
* @throws ParameterException on a parameter error
|
||||||
|
*/
|
||||||
|
Double nextDouble() throws ParameterException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the next boolean, which may come from the stack or a value flag.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
* @throws ParameterException on a parameter error
|
||||||
|
*/
|
||||||
|
Boolean nextBoolean() throws ParameterException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all remaining string values, which will consume the rest of the stack.
|
||||||
|
*
|
||||||
|
* @return the value
|
||||||
|
* @throws ParameterException on a parameter error
|
||||||
|
*/
|
||||||
|
String remaining() throws ParameterException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set as completely consumed.
|
||||||
|
*/
|
||||||
|
void markConsumed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the underlying context.
|
||||||
|
*
|
||||||
|
* @return the context
|
||||||
|
*/
|
||||||
|
CommandContext getContext();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the current position of the stack.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*/
|
||||||
|
void mark();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset to the previously {@link #mark()}ed position of the stack, and return
|
||||||
|
* the arguments that were consumed between this point and that previous point.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*
|
||||||
|
* @return the consumed arguments
|
||||||
|
*/
|
||||||
|
String reset();
|
||||||
|
|
||||||
|
static Class<ArgumentStack> inject0() {
|
||||||
|
return ArgumentStack.class;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util.command.parametric;
|
||||||
|
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
|
import com.sk89q.worldedit.util.command.MissingParameterException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Makes an instance of a {@link CommandContext} into a stack of arguments
|
||||||
|
* that can be consumed.
|
||||||
|
*
|
||||||
|
* @see ParametricBuilder a user of this class
|
||||||
|
*/
|
||||||
|
public class ContextArgumentStack implements ArgumentStack {
|
||||||
|
|
||||||
|
private final CommandContext context;
|
||||||
|
private int index = 0;
|
||||||
|
private int markedIndex = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance using the given context.
|
||||||
|
*
|
||||||
|
* @param context the context
|
||||||
|
*/
|
||||||
|
public ContextArgumentStack(CommandContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return context.getString(index++);
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
throw new MissingParameterException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer nextInt() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(next());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ParameterException(
|
||||||
|
"Expected a number, got '" + context.getString(index - 1) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double nextDouble() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(next());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ParameterException(
|
||||||
|
"Expected a number, got '" + context.getString(index - 1) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean nextBoolean() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return next().equalsIgnoreCase("true");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
throw new MissingParameterException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String remaining() throws ParameterException {
|
||||||
|
try {
|
||||||
|
String value = context.getJoinedStrings(index);
|
||||||
|
index = context.argsLength();
|
||||||
|
return value;
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
throw new MissingParameterException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unconsumed arguments left over, without touching the stack.
|
||||||
|
*
|
||||||
|
* @return the unconsumed arguments
|
||||||
|
*/
|
||||||
|
public String getUnconsumed() {
|
||||||
|
if (index >= context.argsLength()) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return context.getJoinedStrings(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markConsumed() {
|
||||||
|
index = context.argsLength();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the current position.
|
||||||
|
*
|
||||||
|
* @return the position
|
||||||
|
*/
|
||||||
|
public int position() {
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the current position of the stack.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mark() {
|
||||||
|
markedIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset to the previously {@link #mark()}ed position of the stack, and return
|
||||||
|
* the arguments that were consumed between this point and that previous point.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*
|
||||||
|
* @return the consumed arguments
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String reset() {
|
||||||
|
String value = context.getString(markedIndex, index - 1);
|
||||||
|
index = markedIndex;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return whether any arguments were consumed between the marked position
|
||||||
|
* and the current position.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*
|
||||||
|
* @return true if values were consumed.
|
||||||
|
*/
|
||||||
|
public boolean wasConsumed() {
|
||||||
|
return markedIndex != index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the arguments that were consumed between this point and that marked point.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*
|
||||||
|
* @return the consumed arguments
|
||||||
|
*/
|
||||||
|
public String getConsumed() {
|
||||||
|
return context.getString(markedIndex, index);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the underlying context.
|
||||||
|
*
|
||||||
|
* @return the context
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public CommandContext getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> inject() {
|
||||||
|
return ContextArgumentStack.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -219,13 +219,15 @@ public class ParametricCallable implements CommandCallable {
|
|||||||
ArgumentStack usedArguments = getScopedContext(parameter, arguments);
|
ArgumentStack usedArguments = getScopedContext(parameter, arguments);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
usedArguments.mark();
|
||||||
args[i] = parameter.getBinding().bind(parameter, usedArguments, false);
|
args[i] = parameter.getBinding().bind(parameter, usedArguments, false);
|
||||||
} catch (MissingParameterException e) {
|
} catch (ParameterException e) {
|
||||||
// Not optional? Then we can't execute this command
|
// Not optional? Then we can't execute this command
|
||||||
if (!parameter.isOptional()) {
|
if (!parameter.isOptional()) {
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usedArguments.reset();
|
||||||
args[i] = getDefaultValue(i, arguments);
|
args[i] = getDefaultValue(i, arguments);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -254,6 +256,7 @@ public class ParametricCallable implements CommandCallable {
|
|||||||
} catch (UnconsumedParameterException e) {
|
} catch (UnconsumedParameterException e) {
|
||||||
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), this, true);
|
throw new InvalidUsageException("Too many parameters! Unused parameters: " + e.getUnconsumed(), this, true);
|
||||||
} catch (ParameterException e) {
|
} catch (ParameterException e) {
|
||||||
|
e.printStackTrace();
|
||||||
assert parameter != null;
|
assert parameter != null;
|
||||||
String name = parameter.getName();
|
String name = parameter.getName();
|
||||||
|
|
||||||
|
@ -0,0 +1,157 @@
|
|||||||
|
/*
|
||||||
|
* WorldEdit, a Minecraft world manipulation toolkit
|
||||||
|
* Copyright (C) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (C) WorldEdit team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU Lesser General Public License as published by the
|
||||||
|
* Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||||
|
* for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldedit.util.command.parametric;
|
||||||
|
|
||||||
|
import com.sk89q.minecraft.util.commands.CommandContext;
|
||||||
|
import com.sk89q.worldedit.util.command.MissingParameterException;
|
||||||
|
import com.sk89q.util.StringUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A virtual scope that does not actually read from the underlying
|
||||||
|
* {@link CommandContext}.
|
||||||
|
*/
|
||||||
|
public class StringArgumentStack implements ArgumentStack {
|
||||||
|
|
||||||
|
private final boolean nonNullBoolean;
|
||||||
|
private final CommandContext context;
|
||||||
|
private final String[] arguments;
|
||||||
|
private int markedIndex = 0;
|
||||||
|
private int index = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance using the given context.
|
||||||
|
*
|
||||||
|
* @param context the context
|
||||||
|
* @param arguments a list of arguments
|
||||||
|
* @param nonNullBoolean true to have {@link #nextBoolean()} return false instead of null
|
||||||
|
*/
|
||||||
|
public StringArgumentStack(
|
||||||
|
CommandContext context, String[] arguments, boolean nonNullBoolean) {
|
||||||
|
this.context = context;
|
||||||
|
this.arguments = arguments;
|
||||||
|
this.nonNullBoolean = nonNullBoolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new instance using the given context.
|
||||||
|
*
|
||||||
|
* @param context the context
|
||||||
|
* @param arguments an argument string to be parsed
|
||||||
|
* @param nonNullBoolean true to have {@link #nextBoolean()} return false instead of null
|
||||||
|
*/
|
||||||
|
public StringArgumentStack(
|
||||||
|
CommandContext context, String arguments, boolean nonNullBoolean) {
|
||||||
|
this.context = context;
|
||||||
|
this.arguments = CommandContext.split(arguments);
|
||||||
|
this.nonNullBoolean = nonNullBoolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String next() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return arguments[index++];
|
||||||
|
} catch (ArrayIndexOutOfBoundsException e) {
|
||||||
|
throw new MissingParameterException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Integer nextInt() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return Integer.parseInt(next());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ParameterException(
|
||||||
|
"Expected a number, got '" + context.getString(index - 1) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Double nextDouble() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return Double.parseDouble(next());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
throw new ParameterException(
|
||||||
|
"Expected a number, got '" + context.getString(index - 1) + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Boolean nextBoolean() throws ParameterException {
|
||||||
|
try {
|
||||||
|
return next().equalsIgnoreCase("true");
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
if (nonNullBoolean) { // Special case
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new MissingParameterException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String remaining() throws ParameterException {
|
||||||
|
try {
|
||||||
|
String value = StringUtil.joinString(arguments, " ", index);
|
||||||
|
markConsumed();
|
||||||
|
return value;
|
||||||
|
} catch (IndexOutOfBoundsException e) {
|
||||||
|
throw new MissingParameterException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void markConsumed() {
|
||||||
|
index = arguments.length;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CommandContext getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the current position of the stack.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void mark() {
|
||||||
|
markedIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reset to the previously {@link #mark()}ed position of the stack, and return
|
||||||
|
* the arguments that were consumed between this point and that previous point.
|
||||||
|
*
|
||||||
|
* <p>The marked position initially starts at 0.</p>
|
||||||
|
*
|
||||||
|
* @return the consumed arguments
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String reset() {
|
||||||
|
String value = context.getString(markedIndex, index - 1);
|
||||||
|
index = markedIndex;
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Class<?> inject() {
|
||||||
|
return StringArgumentStack.class;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user