Various command (use es6 if java9 + nashorn)

This commit is contained in:
Jesse Boyd
2018-08-22 03:22:37 +10:00
parent 43531a0da0
commit c55353e5b1
59 changed files with 1799 additions and 612 deletions

View File

@ -72,6 +72,7 @@ public class SimpleDispatcher implements Dispatcher {
continue;
} else {
Fawe.debug("Replacing commands is currently undefined behavior: " + StringMan.getString(alias));
commands.put(lower, mapping);
continue;
}
}

View File

@ -86,8 +86,8 @@ public final class PrimitiveBindings extends BindingHelper {
* @throws ParameterException on error
*/
@BindingMatch(type = { Boolean.class, boolean.class },
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
behavior = BindingBehavior.CONSUMES,
consumedCount = 1)
public Boolean getBoolean(ArgumentStack context) throws ParameterException {
return context.nextBoolean();
}
@ -117,7 +117,6 @@ public final class PrimitiveBindings extends BindingHelper {
throw new ParameterException(String.format(
"Expected '%s' to be a number or valid math expression (error: %s)", input, e.getMessage()));
}
}
}

View File

@ -1,14 +1,14 @@
package com.sk89q.worldedit.util.command.parametric;
import com.boydti.fawe.command.SuggestInputParseException;
import com.boydti.fawe.config.BBC;
import com.boydti.fawe.util.chat.UsageMessage;
import com.sk89q.minecraft.util.commands.*;
import com.sk89q.worldedit.WorldEdit;
import com.sk89q.worldedit.util.command.*;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.*;
public abstract class AParametricCallable implements CommandCallable {
// private final ParametricBuilder builder;
@ -206,101 +206,95 @@ public abstract class AParametricCallable implements CommandCallable {
@Override
public List<String> getSuggestions(String arguments, CommandLocals locals) throws CommandException {
String[] split = ("ignored" + " " + arguments).split(" ", -1);
// &a<current> &f<next>
// &cerrors
CommandContext context = new CommandContext(split, getValueFlags(), !arguments.endsWith(" "), locals);
ContextArgumentStack scoped = new ContextArgumentStack(context);
SuggestionContext suggestable = context.getSuggestionContext();
List<String> suggestions = new ArrayList<>(2);
ParameterData parameter = null;
ParameterData[] parameters = getParameters();
String consumed = "";
// For /command -f |
// For /command -f flag|
if (suggestable.forFlag()) {
for (int i = 0; i < getParameters().length; i++) {
ParameterData parameter = getParameters()[i];
boolean hasSuggestion = false;
int maxConsumedI = 0; // The maximum argument index
int minConsumedI = 0; // The minimum argument that has been consumed
// Collect parameters
try {
for (;maxConsumedI < parameters.length; maxConsumedI++) {
parameter = parameters[maxConsumedI];
if (parameter.getBinding().getBehavior(parameter) != BindingBehavior.PROVIDES) {
// Parse the user input into a method argument
ArgumentStack usedArguments = getScopedContext(parameter, scoped);
if (parameter.getFlag() == suggestable.getFlag()) {
String prefix = context.getFlag(parameter.getFlag());
if (prefix == null) {
prefix = "";
}
// System.out.println("(0) Return get binding suggestions " + parameter + " | " + prefix);
return parameter.getBinding().getSuggestions(parameter, prefix);
}
}
// This should not happen
// System.out.println("(1) This should not happen");
return new ArrayList<String>();
}
int consumerIndex = 0;
ParameterData lastConsumer = null;
String lastConsumed = null;
for (int i = 0; i < getParameters().length; i++) {
ParameterData parameter = getParameters()[i];
if (parameter.getFlag() != null) {
continue; // We already handled flags
}
try {
scoped.mark();
parameter.getBinding().bind(parameter, scoped, true);
if (scoped.wasConsumed()) {
lastConsumer = parameter;
lastConsumed = context.getString(scoped.position() - 1);
consumerIndex++;
}
} catch (MissingParameterException e) {
// For /command value1 |value2
// For /command |value1 value2
if (suggestable.forHangingValue()) {
// System.out.println("(2) Return get binding dangling " + parameter + " | " + "");
return parameter.getBinding().getSuggestions(parameter, "");
} else {
// For /command value1| value2
if (lastConsumer != null) {
// System.out.println("(3) Return get consumed " + lastConsumer + " | " + lastConsumed);
return lastConsumer.getBinding().getSuggestions(lastConsumer, lastConsumed);
// For /command| value1 value2
// This should never occur
} else {
// System.out.println("(4) Invalid suggestion context");
throw new RuntimeException("Invalid suggestion context");
usedArguments.mark();
try {
parameter.getBinding().bind(parameter, usedArguments, false);
minConsumedI = maxConsumedI + 1;
} catch (Throwable e) {
while (e.getCause() != null && !(e instanceof ParameterException || e instanceof InvocationTargetException)) e = e.getCause();
consumed = usedArguments.reset();
// Not optional? Then we can't execute this command
if (!parameter.isOptional()) {
if (!(e instanceof MissingParameterException)) minConsumedI = maxConsumedI;
throw e;
}
}
}
} catch (ParameterException | InvocationTargetException e) {
SuggestInputParseException suggestion = SuggestInputParseException.get(e);
if (suggestion != null) {
// System.out.println("(5) Has suggestion " + suggestion.getSuggestions());
return suggestion.getSuggestions();
}
if (suggestable.forHangingValue()) {
String name = getDescription().getParameters().get(consumerIndex).getName();
// System.out.println("(6) Has dangling invalid " + name + " | " + e.getMessage());
throw new InvalidUsageException("For parameter '" + name + "': " + e.getMessage(), this);
} else {
// System.out.println("(7) HGet binding suggestions " + parameter + " | " + lastConsumed);
return parameter.getBinding().getSuggestions(parameter, "");
}
}
}
// For /command value1 value2 |
if (suggestable.forHangingValue()) {
// There's nothing that we can suggest because there's no more parameters
// to add on, and we can't change the previous parameter
// System.out.println("(7.1) No more parameters");
return new ArrayList<String>();
} else {
// For /command value1 value2|
if (lastConsumer != null) {
// System.out.println("(8) Get binding suggestions " + lastConsumer + " | " + lastConsumed);
return lastConsumer.getBinding().getSuggestions(lastConsumer, lastConsumed);
// This should never occur
if (minConsumedI >= maxConsumedI && (parameter == null || parameter.getType() == CommandContext.class)) checkUnconsumed(scoped);
} catch (MissingParameterException ignore) {
} catch (UnconsumedParameterException e) {
suggestions.add(BBC.color("&cToo many parameters! Unused parameters: " + e.getUnconsumed()));
} catch (ParameterException e) {
String name = parameter.getName();
suggestions.add(BBC.color("&cFor parameter '" + name + "': " + e.getMessage()));
} catch (InvocationTargetException e) {
SuggestInputParseException suggestion = SuggestInputParseException.get(e);
if (suggestion != null && !suggestion.getSuggestions().isEmpty()) {
hasSuggestion = true;
suggestions.addAll(suggestion.getSuggestions());
} else {
// System.out.println("(9) Invalid suggestion context");
throw new RuntimeException("Invalid suggestion context");
Throwable t = e;
while (t.getCause() != null) t = t.getCause();
String msg = t.getMessage();
String name = parameter.getName();
if (msg != null && !msg.isEmpty()) suggestions.add(BBC.color("&cFor parameter '" + name + "': " + msg));
}
} catch (Throwable t) {
t.printStackTrace();
throw new WrappedCommandException(t);
}
// If there's 1 or less suggestions already, then show parameter suggestion
if (!hasSuggestion && suggestions.size() <= 1) {
StringBuilder suggestion = new StringBuilder();
outer:
for (String prefix = ""; minConsumedI < parameters.length; minConsumedI++) {
parameter = parameters[minConsumedI];
if (parameter.getBinding().getBehavior(parameter) != BindingBehavior.PROVIDES) {
suggestion.append(prefix);
List<String> argSuggestions = parameter.getBinding().getSuggestions(parameter, consumed);
switch (argSuggestions.size()) {
case 0:
break;
case 1:
suggestion.append(argSuggestions.iterator().next());
break;
default:
suggestion.setLength(0);
suggestions.addAll(argSuggestions);
break outer;
}
consumed = "";
prefix = " ";
}
}
if (suggestion.length() != 0) suggestions.add(suggestion.toString());
}
return suggestions;
}
}

View File

@ -191,9 +191,11 @@ public class BindingHelper implements Binding {
char bracket = parameter.isOptional() ? '[' : '<';
char endBracket = StringMan.getMatchingBracket(bracket);
StringBuilder result = new StringBuilder();
result.append("\u00A75");
result.append(bracket);
result.append("\u00A7r");
if (parameter.getFlag() != null) {
result.append('-').append(parameter.getFlag()).append(' ');
result.append('-').append(parameter.getFlag()).append("\u00A75 \u00A7r");
}
result.append(parameter.getName());
if (parameter.getDefaultValue() != null) {
@ -203,7 +205,9 @@ public class BindingHelper implements Binding {
if (range != null) {
result.append('|').append(StringMan.prettyFormat(range.min())).append(",").append(StringMan.prettyFormat(range.max()));
}
result.append("\u00A75");
result.append(endBracket);
result.append("\u00A7r");
return Collections.singletonList(result.toString());
}
return new ArrayList<>();

View File

@ -139,7 +139,7 @@ public class ContextArgumentStack implements ArgumentStack {
*/
@Override
public String reset() {
String value = context.getString(markedIndex, index - 1);
String value = (index - 1 > markedIndex) ? context.getString(markedIndex, index - 1) : "";
index = markedIndex;
return value;
}

View File

@ -28,7 +28,9 @@
* THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.thoughtworks.paranamer;
package com.sk89q.worldedit.util.command.parametric;
import com.thoughtworks.paranamer.CachingParanamer;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;

View File

@ -31,27 +31,8 @@ public class FunctionParametricCallable extends AParametricCallable {
this.function = function;
this.group = group;
List<String> paramNames = new ArrayList<>();
List<String> typeStrings = new ArrayList<>();
List<Type> types = new ArrayList<>();
List<Object[]> paramParsables = new ArrayList<>();
{
boolean checkType = false;
for (String argument : arguments) {
if (checkType) {
typeStrings.set(typeStrings.size() - 1, argument);
} else {
checkType = false;
if (argument.equals("=")) {
checkType = true;
} else if (argument.length() == 1 && command.flags().contains(argument)) {
typeStrings.add("java.lang.Boolean");
paramNames.add(argument);
} else {
typeStrings.add("java.lang.String");
paramNames.add(argument);
}
}
}
Map<Type, Binding> bindings = builder.getBindings();
Map<String, Type> unqualified = new HashMap<>();
for (Map.Entry<Type, Binding> entry : bindings.entrySet()) {
@ -60,14 +41,46 @@ public class FunctionParametricCallable extends AParametricCallable {
unqualified.put(typeStr, type);
unqualified.put(typeStr.substring(typeStr.lastIndexOf('.') + 1), type);
}
for (String typeStr : typeStrings) {
Type type = unqualified.get(typeStr);
if (type == null) type = unqualified.get("java.lang.String");
types.add(type);
{
Object[] param = null; // name | type | optional value
boolean checkEq = false;
int checkEqI = 0;
for (int i = 0; i < arguments.size(); i++) {
String arg = arguments.get(i);
if (arg.equals("=")) {
checkEqI++;
checkEq = true;
} else if (param == null || !checkEq) {
if (param != null) paramParsables.add(param);
param = new Object[3];
param[0] = arg;
if (arg.length() == 1 && command.flags().contains(arg)) {
param[1] = Boolean.class;
} else {
param[1] = String.class;
}
param[2] = null;
checkEqI = 0;
checkEq = false;
} else {
if (checkEqI == 1) {
param[1] = unqualified.getOrDefault(arg, String.class);
checkEq = false;
}
else if (checkEqI == 2) {
char c = arg.charAt(0);
if (c == '\'' || c == '"') arg = arg.substring(1, arg.length() - 1);
param[2] = arg;
checkEqI = 0;
checkEq = false;
}
}
}
if (param != null) paramParsables.add(param);
}
}
parameters = new ParameterData[paramNames.size()];
parameters = new ParameterData[paramParsables.size()];
List<Parameter> userParameters = new ArrayList<Parameter>();
// This helps keep tracks of @Nullables that appear in the middle of a list
@ -75,20 +88,25 @@ public class FunctionParametricCallable extends AParametricCallable {
int numOptional = 0;
//
// Go through each parameter
for (int i = 0; i < types.size(); i++) {
Type type = types.get(i);
for (int i = 0; i < paramParsables.size(); i++) {
Object[] parsable = paramParsables.get(i);
String paramName = (String) parsable[0];
Type type = (Type) parsable[1];
String optional = (String) parsable[2];
ParameterData parameter = new ParameterData();
parameter.setType(type);
parameter.setModifiers(new Annotation[0]);
String paramName = paramNames.get(i);
boolean flag = paramName.length() == 1 && command.flags().contains(paramName);
if (flag) {
parameter.setFlag(paramName.charAt(0), type != boolean.class && type != Boolean.class);
}
// TODO switch / Optional / Search for annotations /
if (optional != null) {
parameter.setOptional(true);
if (!optional.equalsIgnoreCase("null")) parameter.setDefaultValue(new String[]{optional});
}
parameter.setName(paramName);
@ -256,7 +274,6 @@ public class FunctionParametricCallable extends AParametricCallable {
// postInvoke handlers
{
}
return result;
} catch (MissingParameterException e) {

View File

@ -45,7 +45,6 @@ import com.sk89q.worldedit.util.command.ProcessedCallable;
import com.sk89q.worldedit.util.command.binding.PrimitiveBindings;
import com.sk89q.worldedit.util.command.binding.StandardBindings;
import com.sk89q.worldedit.util.command.binding.Switch;
import com.thoughtworks.paranamer.FaweParanamer;
import com.thoughtworks.paranamer.Paranamer;
import java.lang.reflect.Method;
import java.lang.reflect.Type;

View File

@ -146,7 +146,7 @@ public class StringArgumentStack implements ArgumentStack {
*/
@Override
public String reset() {
String value = context.getString(markedIndex, index - 1);
String value = (index - 1 > markedIndex) ? context.getString(markedIndex, index - 1) : "";
index = markedIndex;
return value;
}