Skip to content

Commit

Permalink
Make event parsing more reliable (#5900)
Browse files Browse the repository at this point in the history
* Make event parsing more reliable

* Switch to parse marks

* Requested Changes

Co-authored-by: LimeGlass <[email protected]>

* Switch to parse tags

---------

Co-authored-by: LimeGlass <[email protected]>
Co-authored-by: Moderocky <[email protected]>
Co-authored-by: sovdee <[email protected]>
  • Loading branch information
4 people authored Nov 30, 2023
1 parent 90d211a commit fccb68e
Show file tree
Hide file tree
Showing 6 changed files with 140 additions and 40 deletions.
13 changes: 4 additions & 9 deletions src/main/java/ch/njol/skript/Skript.java
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,7 @@ public boolean check(final @Nullable ExpressionInfo<?, ?> i) {

// ================ EVENTS ================

private static final List<SkriptEventInfo<?>> events = new ArrayList<>(50);
private static final List<StructureInfo<? extends Structure>> structures = new ArrayList<>(10);

/**
Expand Down Expand Up @@ -1468,10 +1469,10 @@ public static <E extends SkriptEvent> SkriptEventInfo<E> 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<E> r = new SkriptEventInfo<>(name, transformedPatterns, c, originClassPath, events);
structures.add(r);
Skript.events.add(r);
return r;
}

Expand All @@ -1489,14 +1490,8 @@ public static <E extends Structure> void registerStructure(Class<E> c, EntryVali
structures.add(structureInfo);
}

/**
* Modifications made to the returned Collection will not be reflected in the events available for parsing.
*/
public static Collection<SkriptEventInfo<?>> getEvents() {
// Only used in documentation generation, so generating a new list each time is fine
return (Collection<SkriptEventInfo<?>>) (Collection<?>) structures.stream()
.filter(info -> info instanceof SkriptEventInfo)
.collect(Collectors.toList());
return events;
}

public static List<StructureInfo<? extends Structure>> getStructures() {
Expand Down
3 changes: 1 addition & 2 deletions src/main/java/ch/njol/skript/doc/HTMLGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down
36 changes: 12 additions & 24 deletions src/main/java/ch/njol/skript/lang/SkriptEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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<? extends Structure> syntaxElementInfo = getParser().getData(StructureData.class).getStructureInfo();
if (!(syntaxElementInfo instanceof SkriptEventInfo))
Expand Down Expand Up @@ -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());
}

}
2 changes: 0 additions & 2 deletions src/main/java/ch/njol/skript/lang/SkriptEventInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,6 @@

public final class SkriptEventInfo<E extends SkriptEvent> extends StructureInfo<E> {

public static final String EVENT_PRIORITY_SYNTAX = " [with priority (lowest|low|normal|high|highest|monitor)]";

public Class<? extends Event>[] events;
public final String name;

Expand Down
117 changes: 117 additions & 0 deletions src/main/java/ch/njol/skript/structures/StructEvent.java
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*
* 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;
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<? extends StructureInfo<? extends Structure>> iterator) {
ParserInstance.get().getData(StructureData.class).sectionNode = sectionNode;

Iterator<StructureInfo<? extends Structure>> 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);
Expand Down

0 comments on commit fccb68e

Please sign in to comment.