Archived
0
This commit is contained in:
Dico
2018-09-26 12:38:55 +01:00
parent c6c1bbf670
commit ed3c85951a
5 changed files with 190 additions and 113 deletions

View File

@@ -5,9 +5,6 @@ import io.dico.dicore.exceptions.checkedfunctions.CheckedRunnable;
import org.bukkit.command.CommandSender;
import org.jetbrains.annotations.NotNull;
import java.util.List;
import java.util.Objects;
public interface IContextFilter extends Comparable<IContextFilter> {
/**

View File

@@ -0,0 +1,162 @@
package io.dico.dicore.command.parameter;
public class ArgumentMergingPreProcessor implements IArgumentPreProcessor {
private final String tokens;
private final char escapeChar;
public ArgumentMergingPreProcessor(String tokens, char escapeChar) {
if ((tokens.length() & 1) != 0 || tokens.isEmpty()) throw new IllegalArgumentException();
this.tokens = tokens;
this.escapeChar = escapeChar;
}
@Override
public String[] process(int argStart, String[] args) {
if (!(0 <= argStart && argStart <= args.length)) {
throw new IndexOutOfBoundsException();
}
Parser parser = new Parser(argStart, args.clone());
return parser.doProcess();
}
private class Parser {
private final int argStart;
private final String[] args;
private int currentIndex;
private int sectionStart;
private char closingToken;
private int sectionEnd;
private int removeCount;
Parser(int argStart, String[] args) {
this.argStart = argStart;
this.args = args;
}
private void reset() {
removeCount = 0;
closingToken = 0;
sectionStart = -1;
sectionEnd = -1;
currentIndex = argStart;
}
private boolean findNextSectionStart() {
while (currentIndex < args.length) {
String arg = args[currentIndex];
if (arg == null) {
throw new IllegalArgumentException();
}
if (arg.isEmpty()) {
++currentIndex;
continue;
}
int openingTokenIndex = tokens.indexOf(arg.charAt(0));
if (openingTokenIndex == -1 || (openingTokenIndex & 1) != 0) {
++currentIndex;
continue;
}
// found
closingToken = tokens.charAt(openingTokenIndex | 1);
sectionStart = currentIndex;
return true;
}
return false;
}
private boolean findNextSectionEnd() {
while (currentIndex < args.length) {
String arg = args[currentIndex];
if (arg == null) {
throw new IllegalArgumentException();
}
if (arg.isEmpty()
|| arg.charAt(arg.length() - 1) != closingToken
|| (sectionStart == currentIndex && arg.length() == 1)) {
++currentIndex;
continue;
}
if (escapeChar != 0
&& arg.length() > 1
&& arg.charAt(arg.length() - 2) == escapeChar) {
// escaped
++currentIndex;
continue;
}
// found
closingToken = 0;
sectionEnd = currentIndex;
++currentIndex;
return true;
}
return false;
}
private void processFoundSection() {
if (sectionStart == sectionEnd) {
String arg = args[sectionStart];
args[sectionStart] = arg.substring(1, arg.length() - 1);
return;
}
removeCount += sectionEnd - sectionStart;
StringBuilder sb = new StringBuilder();
sb.append(args[sectionStart].substring(1));
for (int i = sectionStart + 1; i < sectionEnd; i++) {
sb.append(' ');
sb.append(args[i]);
args[i] = null;
}
sb.append(' ');
sb.append(args[sectionEnd].substring(0, args[sectionEnd].length() - 1));
args[sectionEnd] = null;
args[sectionStart] = sb.toString();
sectionStart = -1;
sectionEnd = -1;
}
public String[] doProcess() {
reset();
while (findNextSectionStart()) {
if (findNextSectionEnd()) {
processFoundSection();
} else {
currentIndex = sectionStart + 1;
}
}
if (removeCount == 0) {
return args;
}
String[] result = new String[args.length - removeCount];
int i = 0;
for (String arg : args) {
if (arg != null) {
result[i++] = arg;
}
}
return result;
}
}
}

View File

@@ -27,100 +27,7 @@ public interface IArgumentPreProcessor {
* @return The IArgumentPreProcessor
*/
static IArgumentPreProcessor mergeOnTokens(String tokens, char escapeChar) {
if (tokens.isEmpty() || (tokens.length() & 1) != 0) {
throw new IllegalArgumentException();
}
return (argStart, args) -> {
if (!(0 <= argStart && argStart <= args.length)) {
throw new IndexOutOfBoundsException();
}
args = args.clone();
int removeCount = 0;
int closingTokenIdx = 0;
int sectionStart = -1;
for (int i = argStart; i < args.length; i++) {
String arg = args[i];
if (arg == null || arg.isEmpty()) {
continue;
}
if (closingTokenIdx != 0) {
int idx = tokens.indexOf(arg.charAt(arg.length() - 1));
if (idx == closingTokenIdx) {
// count escape chars
int index = arg.length() - 1;
int count = 0;
while (index > 0 && arg.charAt(--index) == escapeChar) {
count++;
}
// remove the final char plus half the count, rounding upwards.
args[i] = arg.substring(0, args.length - 1 - (count + 1) / 2);
if ((count & 1) == 0) {
// not escaped
StringBuilder concat = new StringBuilder(args[sectionStart].substring(1));
for (int j = sectionStart + 1; j <= i; j++) {
concat.append(' ').append(args[j]);
args[j] = null;
removeCount++;
}
args[sectionStart] = concat.toString();
sectionStart = -1;
closingTokenIdx = 0;
} else {
// it's escaped
// add final char because it was escaped
args[i] += tokens.charAt(closingTokenIdx);
}
}
if (i == args.length - 1) {
// if the closing token isn't found, reset state and start from the index subsequent to the one where the opener was found
// it should also undo removal of any escapes... it doesn't do that
i = sectionStart + 1;
closingTokenIdx = 0;
sectionStart = -1;
}
continue;
}
int idx = tokens.indexOf(arg.charAt(0));
if (idx == -1 || (idx & 1) != 0) {
continue;
}
closingTokenIdx = idx | 1;
sectionStart = i;
// make sure to check from the current index for a closer
i--;
}
if (removeCount == 0) {
return args;
}
String[] result = new String[args.length - removeCount];
int i = 0;
for (String arg : args) {
if (arg != null) {
result[i++] = arg;
}
}
return result;
};
return new ArgumentMergingPreProcessor(tokens, escapeChar);
}
}

View File

@@ -66,10 +66,3 @@ private fun Deferred<Any?>.getResult(): String? {
}
return ReflectiveCommand.getResult(getCompleted(), null)
}
fun getNonPrimitiveClass(clazz: Class<*>): Class<*>? {
return if (clazz.isPrimitive)
clazz.kotlin.javaObjectType
else
null
}