From fccb68ea903b5fbfe5e714364a5a9092c8b7e111 Mon Sep 17 00:00:00 2001 From: _tud <98935832+UnderscoreTud@users.noreply.github.com> Date: Thu, 30 Nov 2023 20:16:47 +0300 Subject: [PATCH] Make event parsing more reliable (#5900) * Make event parsing more reliable * Switch to parse marks * Requested Changes Co-authored-by: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> * Switch to parse tags --------- Co-authored-by: LimeGlass <16087552+TheLimeGlass@users.noreply.github.com> Co-authored-by: Moderocky Co-authored-by: sovdee <10354869+sovdeeth@users.noreply.github.com> --- src/main/java/ch/njol/skript/Skript.java | 13 +- .../ch/njol/skript/doc/HTMLGenerator.java | 3 +- .../java/ch/njol/skript/lang/SkriptEvent.java | 36 ++---- .../ch/njol/skript/lang/SkriptEventInfo.java | 2 - .../njol/skript/structures/StructEvent.java | 117 ++++++++++++++++++ .../skript/lang/structure/Structure.java | 9 +- 6 files changed, 140 insertions(+), 40 deletions(-) create mode 100644 src/main/java/ch/njol/skript/structures/StructEvent.java diff --git a/src/main/java/ch/njol/skript/Skript.java b/src/main/java/ch/njol/skript/Skript.java index 9740ee27efa..ae35c08fbf7 100644 --- a/src/main/java/ch/njol/skript/Skript.java +++ b/src/main/java/ch/njol/skript/Skript.java @@ -1436,6 +1436,7 @@ public boolean check(final @Nullable ExpressionInfo i) { // ================ EVENTS ================ + private static final List> events = new ArrayList<>(50); private static final List> structures = new ArrayList<>(10); /** @@ -1468,10 +1469,10 @@ public static SkriptEventInfo registerEvent(String na String[] transformedPatterns = new String[patterns.length]; for (int i = 0; i < patterns.length; i++) - transformedPatterns[i] = "[on] " + SkriptEvent.fixPattern(patterns[i]) + SkriptEventInfo.EVENT_PRIORITY_SYNTAX; + transformedPatterns[i] = SkriptEvent.fixPattern(patterns[i]); SkriptEventInfo r = new SkriptEventInfo<>(name, transformedPatterns, c, originClassPath, events); - structures.add(r); + Skript.events.add(r); return r; } @@ -1489,14 +1490,8 @@ public static void registerStructure(Class c, EntryVali structures.add(structureInfo); } - /** - * Modifications made to the returned Collection will not be reflected in the events available for parsing. - */ public static Collection> getEvents() { - // Only used in documentation generation, so generating a new list each time is fine - return (Collection>) (Collection) structures.stream() - .filter(info -> info instanceof SkriptEventInfo) - .collect(Collectors.toList()); + return events; } public static List> getStructures() { diff --git a/src/main/java/ch/njol/skript/doc/HTMLGenerator.java b/src/main/java/ch/njol/skript/doc/HTMLGenerator.java index 9a4adca6d7b..01a217cc5fb 100644 --- a/src/main/java/ch/njol/skript/doc/HTMLGenerator.java +++ b/src/main/java/ch/njol/skript/doc/HTMLGenerator.java @@ -662,8 +662,7 @@ private String generateEvent(String descTemp, SkriptEventInfo info, @Nullable StringBuilder patterns = new StringBuilder(); for (String line : getDefaultIfNullOrEmpty(info.patterns, "Missing patterns.")) { assert line != null; - line = cleanPatterns(line); - line = line.replace(SkriptEventInfo.EVENT_PRIORITY_SYNTAX, ""); // replace priority syntax in event syntaxes + line = "[on] " + cleanPatterns(line); String parsed = pattern.replace("${element.pattern}", line); patterns.append(parsed); } diff --git a/src/main/java/ch/njol/skript/lang/SkriptEvent.java b/src/main/java/ch/njol/skript/lang/SkriptEvent.java index 1d89b2c6aa9..bbdbd7d170a 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEvent.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEvent.java @@ -25,15 +25,14 @@ import ch.njol.skript.config.SectionNode; import ch.njol.skript.events.EvtClick; import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.structures.StructEvent.EventData; import org.skriptlang.skript.lang.script.Script; import org.skriptlang.skript.lang.entry.EntryContainer; import org.skriptlang.skript.lang.structure.Structure; -import ch.njol.util.StringUtils; import org.bukkit.event.Event; import org.bukkit.event.EventPriority; import org.eclipse.jdt.annotation.Nullable; -import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -64,30 +63,14 @@ public abstract class SkriptEvent extends Structure { @Override public final boolean init(Literal[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) { - String expr = parseResult.expr; - if (StringUtils.startsWithIgnoreCase(expr, "on ")) - expr = expr.substring("on ".length()); - - String[] split = expr.split(" with priority "); - if (split.length != 1) { - if (!isEventPrioritySupported()) { - Skript.error("This event doesn't support event priority"); - return false; - } - - expr = String.join(" with priority ", Arrays.copyOfRange(split, 0, split.length - 1)); + this.expr = parseResult.expr; - String priorityString = split[split.length - 1]; - try { - eventPriority = EventPriority.valueOf(priorityString.toUpperCase()); - } catch (IllegalArgumentException e) { - throw new IllegalStateException(e); - } - } else { - eventPriority = null; + EventPriority priority = getParser().getData(EventData.class).getPriority(); + if (priority != null && !isEventPrioritySupported()) { + Skript.error("This event doesn't support event priority"); + return false; } - - this.expr = parseResult.expr = expr; + eventPriority = priority; SyntaxElementInfo syntaxElementInfo = getParser().getData(StructureData.class).getStructureInfo(); if (!(syntaxElementInfo instanceof SkriptEventInfo)) @@ -253,4 +236,9 @@ public static String fixPattern(String pattern) { return stringBuilder.toString(); } + @Nullable + public static SkriptEvent parse(String expr, SectionNode sectionNode, @Nullable String defaultError) { + return (SkriptEvent) Structure.parse(expr, sectionNode, defaultError, Skript.getEvents().iterator()); + } + } diff --git a/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java b/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java index 3581e655d70..a437bd6e32b 100644 --- a/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java +++ b/src/main/java/ch/njol/skript/lang/SkriptEventInfo.java @@ -29,8 +29,6 @@ public final class SkriptEventInfo extends StructureInfo { - public static final String EVENT_PRIORITY_SYNTAX = " [with priority (lowest|low|normal|high|highest|monitor)]"; - public Class[] events; public final String name; diff --git a/src/main/java/ch/njol/skript/structures/StructEvent.java b/src/main/java/ch/njol/skript/structures/StructEvent.java new file mode 100644 index 00000000000..ceb6fe53f9f --- /dev/null +++ b/src/main/java/ch/njol/skript/structures/StructEvent.java @@ -0,0 +1,117 @@ +/** + * 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.structures; + +import ch.njol.skript.Skript; +import ch.njol.skript.doc.NoDoc; +import ch.njol.skript.lang.Literal; +import ch.njol.skript.lang.SkriptEvent; +import ch.njol.skript.lang.SkriptParser.ParseResult; +import ch.njol.skript.lang.parser.ParserInstance; +import org.bukkit.event.Event; +import org.bukkit.event.EventPriority; +import org.eclipse.jdt.annotation.Nullable; +import org.skriptlang.skript.lang.entry.EntryContainer; +import org.skriptlang.skript.lang.structure.Structure; + +import java.util.Locale; + +@NoDoc +public class StructEvent extends Structure { + + static { + Skript.registerStructure(StructEvent.class, + "[on] <.+> [with priority (:(lowest|low|normal|high|highest|monitor))]"); + } + + private SkriptEvent event; + + @Override + @SuppressWarnings("ConstantConditions") + public boolean init(Literal[] args, int matchedPattern, ParseResult parseResult, EntryContainer entryContainer) { + String expr = parseResult.regexes.get(0).group(); + if (!parseResult.tags.isEmpty()) + getParser().getData(EventData.class).priority = EventPriority.valueOf(parseResult.tags.get(0).toUpperCase(Locale.ENGLISH)); + event = SkriptEvent.parse(expr, entryContainer.getSource(), null); + return event != null; + } + + @Override + public boolean preLoad() { + getParser().setCurrentStructure(event); + return event.preLoad(); + } + + @Override + public boolean load() { + getParser().setCurrentStructure(event); + return event.load(); + } + + @Override + public boolean postLoad() { + getParser().setCurrentStructure(event); + return event.postLoad(); + } + + @Override + public void unload() { + event.unload(); + } + + @Override + public void postUnload() { + event.postUnload(); + } + + @Override + public Priority getPriority() { + return event.getPriority(); + } + + public SkriptEvent getSkriptEvent() { + return event; + } + + @Override + public String toString(@Nullable Event event, boolean debug) { + return this.event.toString(event, debug); + } + + static { + ParserInstance.registerData(EventData.class, EventData::new); + } + + public static class EventData extends ParserInstance.Data { + + @Nullable + private EventPriority priority; + + public EventData(ParserInstance parserInstance) { + super(parserInstance); + } + + @Nullable + public EventPriority getPriority() { + return priority; + } + + } + +} diff --git a/src/main/java/org/skriptlang/skript/lang/structure/Structure.java b/src/main/java/org/skriptlang/skript/lang/structure/Structure.java index 17de96e446c..4852942aafe 100644 --- a/src/main/java/org/skriptlang/skript/lang/structure/Structure.java +++ b/src/main/java/org/skriptlang/skript/lang/structure/Structure.java @@ -174,11 +174,14 @@ public String toString() { @Nullable public static Structure parse(String expr, SectionNode sectionNode, @Nullable String defaultError) { + return parse(expr, sectionNode, defaultError, Skript.getStructures().iterator()); + } + + @Nullable + public static Structure parse(String expr, SectionNode sectionNode, @Nullable String defaultError, Iterator> iterator) { ParserInstance.get().getData(StructureData.class).sectionNode = sectionNode; - Iterator> iterator = - new ConsumingIterator<>(Skript.getStructures().iterator(), - elementInfo -> ParserInstance.get().getData(StructureData.class).structureInfo = elementInfo); + iterator = new ConsumingIterator<>(iterator, elementInfo -> ParserInstance.get().getData(StructureData.class).structureInfo = elementInfo); try (ParseLogHandler parseLogHandler = SkriptLogger.startParseLogHandler()) { Structure structure = SkriptParser.parseStatic(expr, iterator, ParseContext.EVENT, defaultError);