Skip to content
Open
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
7 changes: 7 additions & 0 deletions src/main/java/ch/njol/skript/lang/ExpressionInfo.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package ch.njol.skript.lang;

import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.registration.SyntaxInfo;

/**
* Represents an expression's information, for use when creating new instances of expressions.
Expand All @@ -20,6 +21,12 @@ public ExpressionInfo(String[] patterns, Class<T> returnType, Class<E> expressio
this.expressionType = expressionType;
}

protected ExpressionInfo(SyntaxInfo.Expression<E, T> source) {
super(source);
this.returnType = source.returnType();
this.expressionType = ExpressionType.fromModern(source.priority());
}

/**
* Get the return type of this expression.
* @return The return type of this Expression
Expand Down
47 changes: 32 additions & 15 deletions src/main/java/ch/njol/skript/lang/SkriptEventInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,10 @@
import org.bukkit.event.player.PlayerInteractAtEntityEvent;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos;
import org.skriptlang.skript.lang.structure.StructureInfo;
import org.skriptlang.skript.registration.SyntaxInfo;
import org.skriptlang.skript.registration.SyntaxOrigin;
import org.skriptlang.skript.util.Priority;

import java.lang.reflect.InvocationTargetException;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
Expand Down Expand Up @@ -46,17 +42,7 @@ public sealed class SkriptEventInfo<E extends SkriptEvent> extends StructureInfo
*/
public SkriptEventInfo(String name, String[] patterns, Class<E> eventClass, String originClassPath, Class<? extends Event>[] events) {
super(patterns, eventClass, originClassPath);
for (int i = 0; i < events.length; i++) {
for (int j = i + 1; j < events.length; j++) {
if (events[i].isAssignableFrom(events[j]) || events[j].isAssignableFrom(events[i])) {
if (events[i].equals(PlayerInteractAtEntityEvent.class)
|| events[j].equals(PlayerInteractAtEntityEvent.class))
continue; // Spigot seems to have an exception for those two events...

throw new SkriptAPIException("The event " + name + " (" + eventClass.getName() + ") registers with super/subclasses " + events[i].getName() + " and " + events[j].getName());
}
}
}
validateEvents(name, eventClass, events);

this.events = events;

Expand All @@ -72,6 +58,37 @@ public SkriptEventInfo(String name, String[] patterns, Class<E> eventClass, Stri
// default listening behavior should be dependent on config setting
this.listeningBehavior = SkriptConfig.listenCancelledByDefault.value() ? ListeningBehavior.ANY : ListeningBehavior.UNCANCELLED;
}

protected SkriptEventInfo(BukkitSyntaxInfos.Event<E> source) {
super(source);
//noinspection unchecked
this.events = source.events().toArray(new Class[0]);
this.name = source.name();
validateEvents(name, source.type(), events);
this.id = source.id();
if (source.documentationId() != null)
this.documentationID(source.documentationId());
this.listeningBehavior(source.listeningBehavior())
.since(source.since().toArray(new String[0]))
.description(source.description().toArray(new String[0]))
.examples(source.examples().toArray(new String[0]))
.keywords(source.keywords().toArray(new String[0]))
.requiredPlugins(source.requiredPlugins().toArray(new String[0]));
}

private static void validateEvents(String name, Class<? extends SkriptEvent> eventClass, Class<? extends Event>[] events) {
for (int i = 0; i < events.length; i++) {
for (int j = i + 1; j < events.length; j++) {
if (events[i].isAssignableFrom(events[j]) || events[j].isAssignableFrom(events[i])) {
if (events[i].equals(PlayerInteractAtEntityEvent.class)
|| events[j].equals(PlayerInteractAtEntityEvent.class))
continue; // Spigot seems to have an exception for those two events...

throw new SkriptAPIException("The event " + name + " (" + eventClass.getName() + ") registers with super/subclasses " + events[i].getName() + " and " + events[j].getName());
}
}
}
}

/**
* Sets the default listening behavior for this SkriptEvent. If omitted, the default behavior is to listen to uncancelled events.
Expand Down
57 changes: 24 additions & 33 deletions src/main/java/ch/njol/skript/lang/SyntaxElementInfo.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
package ch.njol.skript.lang;

import org.bukkit.event.Event;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.Unmodifiable;
import org.skriptlang.skript.bukkit.registration.BukkitSyntaxInfos;
import org.skriptlang.skript.registration.SyntaxInfo;
Expand All @@ -23,6 +23,8 @@
*/
public class SyntaxElementInfo<E extends SyntaxElement> implements SyntaxInfo<E> {

private final @Nullable SyntaxInfo<E> source;

// todo: 2.9 make all fields private
public final Class<E> elementClass;
public final String[] patterns;
Expand All @@ -32,6 +34,7 @@ public SyntaxElementInfo(String[] patterns, Class<E> elementClass, String origin
if (Modifier.isAbstract(elementClass.getModifiers()))
throw new SkriptAPIException("Class " + elementClass.getName() + " is abstract");

this.source = null;
this.patterns = patterns;
this.elementClass = elementClass;
this.originClassPath = originClassPath;
Expand All @@ -45,6 +48,13 @@ public SyntaxElementInfo(String[] patterns, Class<E> elementClass, String origin
}
}

public SyntaxElementInfo(SyntaxInfo<E> source) throws IllegalArgumentException {
this.source = source;
this.patterns = source.patterns().toArray(new String[0]);
this.elementClass = source.type();
this.originClassPath = source.origin().name();
}

/**
* Get the class that represents this element.
* @return The Class of the element
Expand Down Expand Up @@ -77,42 +87,14 @@ public static <I extends SyntaxElementInfo<E>, E extends SyntaxElement> I fromMo
if (info instanceof SyntaxElementInfo<? extends E> oldInfo) {
return (I) oldInfo;
} else if (info instanceof BukkitSyntaxInfos.Event<?> event) {
// We must first go back to the raw input
String rawName = event.name().startsWith("On ")
? event.name().substring(3)
: "*" + event.name();
SkriptEventInfo<?> eventInfo = new SkriptEventInfo<>(
rawName, event.patterns().toArray(new String[0]),
event.type(), event.origin().name(),
(Class<? extends Event>[]) event.events().toArray(new Class<?>[0]));
String documentationId = event.documentationId();
if (documentationId != null)
eventInfo.documentationID(documentationId);
eventInfo.listeningBehavior(event.listeningBehavior())
.since(event.since().toArray(new String[0]))
.description(event.description().toArray(new String[0]))
.examples(event.examples().toArray(new String[0]))
.keywords(event.keywords().toArray(new String[0]))
.requiredPlugins(event.requiredPlugins().toArray(new String[0]));

return (I) eventInfo;
return (I) new SkriptEventInfo<>(event);
} else if (info instanceof SyntaxInfo.Structure<?> structure) {
return (I) new StructureInfo<>(structure.patterns().toArray(new String[0]), structure.type(),
structure.origin().name(), structure.entryValidator(), structure.nodeType());
return (I) new StructureInfo<>(structure);
} else if (info instanceof SyntaxInfo.Expression<?, ?> expression) {
return (I) fromModernExpression(expression);
return (I) new ExpressionInfo<>(expression);
}

return (I) new SyntaxElementInfo<>(info.patterns().toArray(new String[0]), info.type(), info.origin().name());
}

@Contract("_ -> new")
@ApiStatus.Experimental
private static <E extends ch.njol.skript.lang.Expression<R>, R> ExpressionInfo<E, R> fromModernExpression(SyntaxInfo.Expression<E, R> info) {
return new ExpressionInfo<>(
info.patterns().toArray(new String[0]), info.returnType(),
info.type(), info.origin().name(), ExpressionType.fromModern(info.priority())
);
return (I) new SyntaxElementInfo<>(info);
}

// Registration API Compatibility
Expand All @@ -127,6 +109,8 @@ public Builder<? extends Builder<?, E>, E> toBuilder() {
@Override
@ApiStatus.Internal
public SyntaxOrigin origin() {
if (source != null)
return source.origin();
return () -> originClassPath;
}

Expand All @@ -139,6 +123,9 @@ public Class<E> type() {
@Override
@ApiStatus.Internal
public E instance() {
if (source != null)
return source.instance();

try {
return type().getDeclaredConstructor().newInstance();
} catch (InstantiationException | IllegalAccessException | InvocationTargetException |
Expand All @@ -150,12 +137,16 @@ public E instance() {
@Override
@ApiStatus.Internal
public @Unmodifiable Collection<String> patterns() {
if (source != null)
return source.patterns();
return List.of(getPatterns());
}

@Override
@ApiStatus.Internal
public Priority priority() {
if (source != null)
source.priority();
return SyntaxInfo.COMBINED;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,19 @@ public StructureInfo(String[] patterns, Class<E> elementClass, String originClas
this.simple = nodeType.canBeSimple();
}

@ApiStatus.Internal
public StructureInfo(SyntaxInfo.Structure<E> source) {
super(source);
this.entryValidator = source.entryValidator();
this.nodeType = source.nodeType();
this.simple = source.nodeType().canBeSimple();
}

protected StructureInfo(SyntaxInfo<E> source) {
super(source);
this.entryValidator = null;
this.nodeType = Structure.NodeType.SIMPLE;
this.simple = nodeType.canBeSimple();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import ch.njol.skript.lang.SkriptEvent;
import ch.njol.skript.lang.SkriptEvent.ListeningBehavior;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.SyntaxElementInfo;
import ch.njol.util.coll.CollectionUtils;
import org.bukkit.event.Event;
import org.bukkit.event.block.BlockEvent;
Expand Down Expand Up @@ -41,6 +42,35 @@ public String toString(@Nullable Event event, boolean debug) {

}

public static final class KeyedMockSkriptEvent extends SkriptEvent {

private final String key;

public KeyedMockSkriptEvent(String key) {
this.key = key;
}

public String key() {
return key;
}

@Override
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult) {
throw new UnsupportedOperationException();
}

@Override
public boolean check(Event event) {
throw new UnsupportedOperationException();
}

@Override
public String toString(@Nullable Event event, boolean debug) {
throw new UnsupportedOperationException();
}

}

@Override
public Builder<?, MockSkriptEvent> builder(boolean addPattern) {
var info = BukkitSyntaxInfos.Event.builder(MockSkriptEvent.class, "mock event");
Expand All @@ -60,6 +90,16 @@ public Supplier<MockSkriptEvent> supplier() {
return MockSkriptEvent::new;
}

@Test
public void testNoNullaryConstructor() {
var info = BukkitSyntaxInfos.Event.builder(KeyedMockSkriptEvent.class, "keyed mock event")
.addPattern("default")
.supplier(() -> new KeyedMockSkriptEvent("Key"))
.build();
var legacy = SyntaxElementInfo.fromModern(info);
assertEquals(legacy.instance().key(), info.instance().key());
}

@Test
public void testListeningBehavior() {
for (final var behavior : ListeningBehavior.values()) {
Expand Down