diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 421eab2f356..4b5dece6ef9 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -1250,6 +1250,8 @@ public static void registerCondition(final Class condit final SyntaxElementInfo info = new SyntaxElementInfo<>(patterns, condition, originClassPath); conditions.add(info); statements.add(info); + // PATTERN_MATCHES_EVERYTHING makes the expression be attempted last + registerExpression(condition, Boolean.class, ExpressionType.PATTERN_MATCHES_EVERYTHING, patterns); } /** diff --git a/src/main/java/ch/njol/skript/conditions/CondExpression.java b/src/main/java/ch/njol/skript/conditions/CondExpression.java new file mode 100644 index 00000000000..1d7802385b9 --- /dev/null +++ b/src/main/java/ch/njol/skript/conditions/CondExpression.java @@ -0,0 +1,59 @@ +/** + * This file is part of Skript. + * + * Skript is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Skript 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Skript. If not, see . + * + * Copyright Peter Güttinger, SkriptLang team and contributors + */ +package ch.njol.skript.conditions; + +import java.util.Objects; + +import org.bukkit.event.Event; +import org.eclipse.jdt.annotation.Nullable; + +import ch.njol.skript.lang.Condition; +import ch.njol.skript.lang.Expression; +import ch.njol.skript.lang.SkriptParser; +import ch.njol.util.Kleenean; + +public class CondExpression extends Condition { + + private final Expression expression; + + public CondExpression(Expression expression) { + Objects.requireNonNull(expression); + this.expression = expression; + } + + @Override + public boolean init(Expression[] exprs, int matchedPattern, Kleenean isDelayed, SkriptParser.ParseResult parseResult) { + throw new IllegalStateException(); + } + + @Override + public boolean check(Event e) { + return expression.check(e, o -> o, false); + } + + @Override + public String toString(@Nullable Event e, boolean debug) { + return expression.toString(e, debug); + } + + public Expression getExpression() { + return expression; + } + +} diff --git a/src/main/java/ch/njol/skript/lang/Condition.java b/src/main/java/ch/njol/skript/lang/Condition.java index a66610b1de2..bbc734e3ba0 100644 --- a/src/main/java/ch/njol/skript/lang/Condition.java +++ b/src/main/java/ch/njol/skript/lang/Condition.java @@ -24,15 +24,22 @@ import org.eclipse.jdt.annotation.Nullable; import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer; +import ch.njol.skript.conditions.CondExpression; +import ch.njol.skript.lang.util.ConvertedExpression; import ch.njol.skript.lang.util.SimpleExpression; +import ch.njol.skript.log.ParseLogHandler; +import ch.njol.skript.log.SkriptLogger; import ch.njol.util.Checker; +import ch.njol.util.coll.CollectionUtils; +import ch.njol.util.coll.iterator.SingleItemIterator; /** * A condition which must be fulfilled for the trigger to continue. If the condition is in a section the behaviour depends on the section. * * @see Skript#registerCondition(Class, String...) */ -public abstract class Condition extends Statement { +public abstract class Condition extends Statement implements Expression { private boolean negated = false; @@ -68,13 +75,123 @@ public final boolean isNegated() { return negated; } - @SuppressWarnings({"rawtypes", "unchecked", "null"}) + @SuppressWarnings({"ConstantConditions", "unchecked"}) @Nullable public static Condition parse(String s, @Nullable String defaultError) { s = s.trim(); while (s.startsWith("(") && SkriptParser.next(s, 0, ParseContext.DEFAULT) == s.length()) s = s.substring(1, s.length() - 1); - return (Condition) SkriptParser.parse(s, (Iterator) Skript.getConditions().iterator(), defaultError); + + Expression expression; + ParseLogHandler logHandler = SkriptLogger.startParseLogHandler(); + try { + expression = new SkriptParser(s).parseExpression(Boolean.class); + if (expression == null) { + logHandler.printError(defaultError); + return null; + } + + logHandler.printLog(); + } finally { + logHandler.stop(); + } + + return expression instanceof Condition ? (Condition) expression : new CondExpression(expression); + } + + @Override + public Boolean getSingle(Event e) { + return check(e); + } + + @Override + public Boolean[] getArray(Event e) { + return new Boolean[] {check(e)}; + } + + @Override + public Boolean[] getAll(Event e) { + return new Boolean[] {check(e)}; + } + + @Override + public boolean isSingle() { + return true; + } + + @Override + public boolean check(Event e, Checker c, boolean negated) { + return SimpleExpression.check(getAll(e), c, negated, getAnd()); + } + + @Override + public boolean check(Event e, Checker c) { + return SimpleExpression.check(getAll(e), c, false, getAnd()); + } + + @SuppressWarnings("unchecked") + @Override + public Expression getConvertedExpression(Class... to) { + if (CollectionUtils.containsSuperclass(to, Boolean.class)) + return (Expression) this; + return ConvertedExpression.newInstance(this, to); + } + + @Override + public Class getReturnType() { + return Boolean.class; + } + + @Override + public boolean getAnd() { + return true; + } + + @Override + public boolean setTime(int time) { + return false; + } + + @Override + public int getTime() { + return 0; + } + + @Override + public boolean isDefault() { + return false; + } + + @Nullable + @Override + public Iterator iterator(Event e) { + return new SingleItemIterator<>(check(e)); + } + + @Override + public boolean isLoopOf(String s) { + return false; + } + + @Override + public Expression getSource() { + return this; + } + + @Override + public Expression simplify() { + return this; + } + + @Nullable + @Override + public Class[] acceptChange(Changer.ChangeMode mode) { + return null; + } + + @Override + public void change(Event e, @Nullable Object[] delta, Changer.ChangeMode mode) { + throw new UnsupportedOperationException(); } }