diff --git a/src/main/java/ch/njol/skript/classes/Changer.java b/src/main/java/ch/njol/skript/classes/Changer.java index 74b0040fe15..5d7dc2973a9 100644 --- a/src/main/java/ch/njol/skript/classes/Changer.java +++ b/src/main/java/ch/njol/skript/classes/Changer.java @@ -42,7 +42,7 @@ public boolean supportsKeyedChange() { /** * @param what The objects to change - * @param delta An array with one or more instances of one or more of the the classes returned by {@link #acceptChange(ChangeMode)} for the given change mode (null for + * @param delta An array with one or more instances of one or more of the classes returned by {@link #acceptChange(ChangeMode)} for the given change mode (null for * {@link ChangeMode#DELETE} and {@link ChangeMode#RESET}). This can be a Object[], thus casting is not allowed. * @param mode The {@link ChangeMode} to test. * @throws UnsupportedOperationException (optional) if this method was called on an unsupported ChangeMode. diff --git a/src/main/java/ch/njol/skript/effects/EffParse.java b/src/main/java/ch/njol/skript/effects/EffParse.java new file mode 100644 index 00000000000..30c78a12d92 --- /dev/null +++ b/src/main/java/ch/njol/skript/effects/EffParse.java @@ -0,0 +1,79 @@ +package ch.njol.skript.effects; + +import ch.njol.skript.Skript; +import ch.njol.skript.classes.Changer.ChangeMode; +import ch.njol.skript.classes.Changer.ChangerUtils; +import ch.njol.skript.classes.ClassInfo; +import ch.njol.skript.classes.Parser; +import ch.njol.skript.lang.*; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.registrations.Classes; +import ch.njol.util.Kleenean; +import org.bukkit.event.Event; +import org.jetbrains.annotations.Nullable; + +public class EffParse extends Effect { + + static { + Skript.registerEffect(EffParse.class, "parse %~strings% as %*classinfo%"); + } + + private Expression toParse; + private ClassInfo classInfo; + + @Override + @SuppressWarnings("unchecked") + public boolean init(Expression[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) { + toParse = (Expression) expressions[0]; + classInfo = ((Literal>) expressions[1]).getSingle(); + + if (classInfo.getC() == String.class) { + Skript.error("Parsing as text is useless as only things that are already text may be parsed"); + return false; + } + + if (toParse == null) { + return false; + } + + Parser parser = classInfo.getParser(); + if (parser == null || !parser.canParse(ParseContext.PARSE)) { + Skript.error("Text cannot be parsed as " + classInfo.getName().withIndefiniteArticle()); + return false; + } + + if (toParse instanceof ExpressionList toParseExpressions) { + for (int i = 0; i < toParseExpressions.getAllExpressions().size(); i++) { + Expression expression = (Expression) toParseExpressions.getAllExpressions().get(i); + if (!ChangerUtils.acceptsChange(expression, ChangeMode.SET, classInfo.getC())) { + Skript.error(toParse + " can't be set to " + classInfo.getName().withIndefiniteArticle()); + return false; + } + } + } else if (!ChangerUtils.acceptsChange(toParse, ChangeMode.SET, classInfo.getC())) { + Skript.error(toParse + " can't be set to " + classInfo.getName().withIndefiniteArticle()); + return false; + } + + return true; + } + + @Override + @SuppressWarnings("unchecked") + protected void execute(Event event) { + if (toParse instanceof ExpressionList toParseExpressions) { + for (int i = 0; i < toParseExpressions.getAllExpressions().size(); i++) { + Expression expression = (Expression) toParseExpressions.getAllExpressions().get(i); + expression.changeInPlace(event, (stringToParse) -> Classes.parseSimple(stringToParse, classInfo.getC(), ParseContext.PARSE)); + } + } else { + toParse.changeInPlace(event, (stringToParse) -> Classes.parseSimple(stringToParse, classInfo.getC(), ParseContext.PARSE)); + } + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return "parse " + toParse + " as " + classInfo.getName().withIndefiniteArticle(); + } + +} diff --git a/src/test/skript/tests/syntaxes/effects/EffParse.sk b/src/test/skript/tests/syntaxes/effects/EffParse.sk new file mode 100644 index 00000000000..b4250c6540a --- /dev/null +++ b/src/test/skript/tests/syntaxes/effects/EffParse.sk @@ -0,0 +1,25 @@ +test "parse effect": + # test single value + set {_value} to "5" + parse {_value} as int + assert {_value} = 5 with "couldn't parse a single value" + + set {_value} to "a" + parse {_value} as int + assert {_value} isn't set with "failed parse didn't delete the value" + + # test lists + set {_values::*} to "1", "2a", "3" + parse {_values::*} as int + assert {_values::1} = 1 with "couldn't parse a list - 1" + assert {_values::2} isn't set with "couldn't parse a list - 2" + assert {_values::3} = 3 with "couldn't parse a list - 3" + + # test multiple expressions + set {_a} to "3" + set {_b} to "hello" + set {_c} to "5" + parse {_a}, {_b} and {_c} as int + assert {_a} = 3 with "couldn't parse multiple expressions - 1" + assert {_b} isn't set with "couldn't parse multiple expressions - 2" + assert {_c} = 5 with "couldn't parse multiple expressions - 3"