diff --git a/src/main/java/ch/njol/skript/lang/SkriptParser.java b/src/main/java/ch/njol/skript/lang/SkriptParser.java index cd1200593c4..4bffc2a4225 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptParser.java +++ b/src/main/java/ch/njol/skript/lang/SkriptParser.java @@ -41,6 +41,7 @@ import ch.njol.skript.patterns.MalformedPatternException; import ch.njol.skript.patterns.PatternCompiler; import ch.njol.skript.patterns.SkriptPattern; +import ch.njol.skript.patterns.TypePatternElement; import ch.njol.skript.registrations.Classes; import ch.njol.skript.util.Utils; import ch.njol.util.Kleenean; @@ -119,6 +120,8 @@ public SkriptParser(SkriptParser other, String expr) { public static final String WILDCARD = "[^\"]*?(?:\"[^\"]*?\"[^\"]*?)*?"; public static class ParseResult { + @Nullable + public SkriptPattern source; public Expression[] exprs; public List regexes = new ArrayList<>(1); public String expr; @@ -236,12 +239,11 @@ private T parse(Iterator types = parseResult.source.getElements(TypePatternElement.class); + for (int i = 0; i < parseResult.exprs.length; i++) { if (parseResult.exprs[i] == null) { - String name = pattern.substring(startIndex + 1, endIndex); - ExprInfo exprInfo = getExprInfo(name); + ExprInfo exprInfo = types.get(i).getExprInfo(); if (!exprInfo.isOptional) { DefaultExpression expr = getDefaultExpression(exprInfo, info.patterns[patternIndex]); if (!expr.init()) @@ -249,7 +251,6 @@ private T parse(Iterator exprInfoCache = new HashMap<>(); - - private static ExprInfo getExprInfo(String string) throws IllegalArgumentException, SkriptAPIException { - ExprInfo exprInfo = exprInfoCache.get(string); - if (exprInfo == null) { - exprInfo = createExprInfo(string); - exprInfoCache.put(string, exprInfo); - } - - return exprInfo; - } - - private static ExprInfo createExprInfo(String string) throws IllegalArgumentException, SkriptAPIException { - ExprInfo exprInfo = new ExprInfo(StringUtils.count(string, '/') + 1); - int caret = 0; - flags: - do { - switch (string.charAt(caret)) { - case '-': - exprInfo.isOptional = true; - break; - case '*': - exprInfo.flagMask &= ~PARSE_EXPRESSIONS; - break; - case '~': - exprInfo.flagMask &= ~PARSE_LITERALS; - break; - default: - break flags; - } - ++caret; - } while (true); - int atSign = string.indexOf('@', caret); - if (atSign != -1) { - exprInfo.time = Integer.parseInt(string.substring(atSign + 1)); - string = string.substring(caret, atSign); - } else { - string = string.substring(caret); - } - String[] classes = string.split("/"); - assert classes.length == exprInfo.classes.length; - for (int i = 0; i < classes.length; i++) { - NonNullPair plural = Utils.getEnglishPlural("" + classes[i]); - exprInfo.classes[i] = Classes.getClassInfo(plural.getFirst()); - exprInfo.isPlural[i] = plural.getSecond(); - } - return exprInfo; - } - /** * @see ParserInstance#get() */ diff --git a/src/main/java/ch/njol/skript/patterns/MatchResult.java b/src/main/java/ch/njol/skript/patterns/MatchResult.java index e0350e2b921..819c78f4361 100644 --- a/src/main/java/ch/njol/skript/patterns/MatchResult.java +++ b/src/main/java/ch/njol/skript/patterns/MatchResult.java @@ -21,6 +21,7 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ParseContext; import ch.njol.skript.lang.SkriptParser.ParseResult; +import com.google.common.base.MoreObjects; import java.util.ArrayList; import java.util.Arrays; @@ -31,6 +32,8 @@ */ public class MatchResult { + SkriptPattern source; + int exprOffset; Expression[] expressions = new Expression[0]; @@ -45,6 +48,7 @@ public class MatchResult { public MatchResult copy() { MatchResult matchResult = new MatchResult(); + matchResult.source = this.source; matchResult.exprOffset = this.exprOffset; matchResult.expressions = this.expressions.clone(); matchResult.expr = this.expr; @@ -58,6 +62,7 @@ public MatchResult copy() { public ParseResult toParseResult() { ParseResult parseResult = new ParseResult(expr, expressions); + parseResult.source = source; parseResult.regexes.addAll(regexResults); parseResult.mark = mark; parseResult.tags.addAll(tags); @@ -86,16 +91,17 @@ public List getRegexResults() { @Override public String toString() { - return "MatchResult{" + - "exprOffset=" + exprOffset + - ", expressions=" + Arrays.toString(expressions) + - ", expr='" + expr + '\'' + - ", mark=" + mark + - ", tags=" + tags + - ", regexResults=" + regexResults + - ", parseContext=" + parseContext + - ", flags=" + flags + - '}'; + return MoreObjects.toStringHelper(this) + .add("source", source) + .add("exprOffset", exprOffset) + .add("expressions", Arrays.toString(expressions)) + .add("expr", expr) + .add("mark", mark) + .add("tags", tags) + .add("regexResults", regexResults) + .add("parseContext", parseContext) + .add("flags", flags) + .toString(); } } diff --git a/src/main/java/ch/njol/skript/patterns/SkriptPattern.java b/src/main/java/ch/njol/skript/patterns/SkriptPattern.java index f43c521b59b..3c89170d97b 100644 --- a/src/main/java/ch/njol/skript/patterns/SkriptPattern.java +++ b/src/main/java/ch/njol/skript/patterns/SkriptPattern.java @@ -21,6 +21,7 @@ import ch.njol.skript.lang.Expression; import ch.njol.skript.lang.ParseContext; import ch.njol.skript.lang.SkriptParser; +import com.google.common.collect.ImmutableList; import org.jetbrains.annotations.Nullable; import java.util.ArrayList; @@ -33,6 +34,8 @@ public class SkriptPattern { private final int expressionAmount; private final String[] keywords; + @Nullable + private List types; public SkriptPattern(PatternElement first, int expressionAmount) { this.first = first; @@ -51,6 +54,7 @@ public MatchResult match(String expr, int flags, ParseContext parseContext) { expr = expr.trim(); MatchResult matchResult = new MatchResult(); + matchResult.source = this; matchResult.expr = expr; matchResult.expressions = new Expression[expressionAmount]; matchResult.parseContext = parseContext; @@ -147,4 +151,45 @@ private static int countNonNullTypes(PatternElement patternElement) { return count; } + /** + * A method to obtain a list of all pattern elements of a specified type that are represented by this SkriptPattern. + * @param type The type of pattern elements to obtain. + * @return A list of all pattern elements of the specified type represented by this SkriptPattern. + * @param The type of pattern element. + */ + public List getElements(Class type) { + if (type == TypePatternElement.class) { + if (types == null) + types = ImmutableList.copyOf(getElements(TypePatternElement.class, first, new ArrayList<>())); + //noinspection unchecked - checked with type == TypePatternElement + return (List) types; + } + return getElements(type, first, new ArrayList<>()); + } + + /** + * A method to obtain a list of all pattern elements of a specified type (from a starting element). + * @param type The type of pattern elements to obtain. + * @param element The element to start searching for other elements from (this will unwrap certain elements). + * @param elements A list to add matching elements to. + * @return A list of all pattern elements of a specified type (from a starting element). + * @param The type of pattern element. + */ + private static List getElements(Class type, PatternElement element, List elements) { + while (element != null) { + if (element instanceof ChoicePatternElement) { + ((ChoicePatternElement) element).getPatternElements().forEach(e -> getElements(type, e, elements)); + } else if (element instanceof GroupPatternElement) { + getElements(type, ((GroupPatternElement) element).getPatternElement(), elements); + } else if (element instanceof OptionalPatternElement) { + getElements(type, ((OptionalPatternElement) element).getPatternElement(), elements); + } else if (type.isInstance(element)) { + //noinspection unchecked - it is checked with isInstance + elements.add((T) element); + } + element = element.originalNext; + } + return elements; + } + }