Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make event parsing more reliable #5900

Merged
merged 7 commits into from
Nov 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
UnderscoreTud marked this conversation as resolved.
Show resolved Hide resolved
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;
UnderscoreTud marked this conversation as resolved.
Show resolved Hide resolved
}

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);
Pikachu920 marked this conversation as resolved.
Show resolved Hide resolved
}

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