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

Sub Entry Validators/Containers #7530

Open
wants to merge 7 commits into
base: dev/feature
Choose a base branch
from
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
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,6 @@
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.lang.TriggerItem;
import org.bukkit.event.Event;
import org.bukkit.event.HandlerList;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.entry.EntryContainer;
import org.skriptlang.skript.lang.entry.EntryValidator;
Expand All @@ -20,13 +18,6 @@

public class StructTestEntryContainer extends Structure {

public static class TestEvent extends Event {
@Override
public @NotNull HandlerList getHandlers() {
throw new IllegalStateException();
}
}

static {
if (TestMode.ENABLED)
Skript.registerStructure(StructTestEntryContainer.class,
Expand Down Expand Up @@ -55,7 +46,7 @@ public boolean load() {
List<TriggerItem> triggerItems = ScriptLoader.loadItems(section);
Script script = getParser().getCurrentScript();
Trigger trigger = new Trigger(script, "entry container test", null, triggerItems);
trigger.execute(new TestEvent());
trigger.execute(new SkriptTestEvent());
return true;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package ch.njol.skript.test.runner;

import ch.njol.skript.ScriptLoader;
import ch.njol.skript.Skript;
import ch.njol.skript.config.SectionNode;
import ch.njol.skript.lang.Literal;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.Trigger;
import ch.njol.skript.lang.TriggerItem;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.entry.ContainerEntryData;
import org.skriptlang.skript.lang.entry.EntryContainer;
import org.skriptlang.skript.lang.entry.EntryValidator;
import org.skriptlang.skript.lang.script.Script;
import org.skriptlang.skript.lang.structure.Structure;

import java.util.List;

public class StructTestSubValidators extends Structure {

static {
if (TestMode.ENABLED)
Skript.registerStructure(StructTestSubValidators.class,
EntryValidator.builder()
.addEntryData(new ContainerEntryData("sub validator 1", false,
EntryValidator.builder()
.addSection("sub section", false)
))
.addEntryData(new ContainerEntryData("sub validator 2", false,
EntryValidator.builder()
.addEntryData(new ContainerEntryData("sub sub validator", false,
EntryValidator.builder()
.addSection("sub sub section", false)
))
))
.build(),
"test sub validators"
);
}

private EntryContainer entryContainer;

@Override
public boolean init(Literal<?>[] args, int matchedPattern, ParseResult parseResult, @Nullable EntryContainer entryContainer) {
this.entryContainer = entryContainer;
return true;
}

@Override
public boolean load() {
EntryContainer subEntry1 = entryContainer.get("sub validator 1", EntryContainer.class, false);
SectionNode section1 = subEntry1.get("sub section", SectionNode.class, false);
EntryContainer subEntry2 = entryContainer.get("sub validator 2", EntryContainer.class, false);
EntryContainer subSubEntry = subEntry2.get("sub sub validator", EntryContainer.class, false);
SectionNode section2 = subSubEntry.get("sub sub section", SectionNode.class, false);

List<TriggerItem> items1 = ScriptLoader.loadItems(section1);
List<TriggerItem> items2 = ScriptLoader.loadItems(section2);
Script script = getParser().getCurrentScript();
Trigger trigger1 = new Trigger(script, "sub section", null, items1);
Trigger trigger2 = new Trigger(script, "sub sub section", null, items2);
trigger1.execute(new SkriptTestEvent());
trigger2.execute(new SkriptTestEvent());
return true;
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "test sub entry validators";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package org.skriptlang.skript.lang.entry;

import ch.njol.skript.ScriptLoader;
import ch.njol.skript.config.Node;
import ch.njol.skript.config.SectionNode;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.entry.EntryValidator.EntryValidatorBuilder;
import org.skriptlang.skript.lang.structure.Structure;

/**
* Virtually the same as {@link EntryValidator}.
* Allows an {@link EntryValidator} used within a {@link Structure} to contain embedded {@link EntryValidator}s.
*/
public class ContainerEntryData extends EntryData<EntryContainer> {

private final EntryValidator entryValidator;
private EntryContainer entryContainer;

public ContainerEntryData(String key, boolean optional, EntryValidator entryValidator) {
super(key, null, optional);
this.entryValidator = entryValidator;
}

public ContainerEntryData(String key, boolean optional, EntryValidatorBuilder validatorBuilder) {
super(key, null, optional);
this.entryValidator = validatorBuilder.build();
}

/**
* Since this will and should never be the main {@link EntryValidator} when used for a {@link Structure}
* We need to validate it when the main {@link EntryValidator} is being validated.
* @param sectionNode
* @return
*/
public boolean validate(SectionNode sectionNode) {
EntryContainer container = entryValidator.validate(sectionNode);
entryContainer = container;
return container != null;
}

@Override
public @Nullable EntryContainer getValue(Node node) {
return entryContainer;
}

@Override
public boolean canCreateWith(Node node) {
if (!(node instanceof SectionNode))
return false;
String key = node.getKey();
if (key == null)
return false;
key = ScriptLoader.replaceOptions(key);
if (!getKey().equalsIgnoreCase(key))
return false;
return validate((SectionNode) node);
}

}
9 changes: 3 additions & 6 deletions src/main/java/org/skriptlang/skript/lang/entry/EntryData.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@
public abstract class EntryData<T> {

private final String key;
@Nullable
private final T defaultValue;
private final @Nullable T defaultValue;
private final boolean optional;

public EntryData(String key, @Nullable T defaultValue, boolean optional) {
Expand All @@ -49,8 +48,7 @@ public String getKey() {
* @return The default value of this entry node to be used if {@link #getValue(Node)} is null,
* or if the user does not include an entry for this entry data within their {@link SectionNode}.
*/
@Nullable
public T getDefaultValue() {
public @Nullable T getDefaultValue() {
return defaultValue;
}

Expand All @@ -66,8 +64,7 @@ public boolean isOptional() {
* @param node The node to obtain a value from.
* @return The value obtained from the provided node.
*/
@Nullable
public abstract T getValue(Node node);
public abstract @Nullable T getValue(Node node);

/**
* A method to be implemented by all entry data classes that determines whether
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,7 @@ public static EntryValidatorBuilder builder() {

private final List<EntryData<?>> entryData;

@Nullable
private final Predicate<Node> unexpectedNodeTester;
private final @Nullable Predicate<Node> unexpectedNodeTester;

private final Function<String, String> unexpectedEntryMessage, missingRequiredEntryMessage;

Expand Down Expand Up @@ -71,8 +70,7 @@ public List<EntryData<?>> getEntryData() {
* The returned map uses the matched entry data's key as a key and uses a pair containing the entry data and matching node
* Will return null if the provided node couldn't be validated.
*/
@Nullable
public EntryContainer validate(SectionNode sectionNode) {
public @Nullable EntryContainer validate(SectionNode sectionNode) {
List<EntryData<?>> entries = new ArrayList<>(entryData);
Map<String, Node> handledNodes = new HashMap<>();
List<Node> unhandledNodes = new ArrayList<>();
Expand Down Expand Up @@ -132,11 +130,9 @@ private EntryValidatorBuilder() { }
private final List<EntryData<?>> entryData = new ArrayList<>();
private String entrySeparator = DEFAULT_ENTRY_SEPARATOR;

@Nullable
private Predicate<Node> unexpectedNodeTester;
private @Nullable Predicate<Node> unexpectedNodeTester;

@Nullable
private Function<String, String> unexpectedEntryMessage, missingRequiredEntryMessage;
private @Nullable Function<String, String> unexpectedEntryMessage, missingRequiredEntryMessage;

/**
* Updates the separator to be used when creating KeyValue entries. Please note
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@ public KeyValueEntryData(String key, @Nullable T defaultValue, boolean optional)
* @return The value obtained from the provided {@link SimpleNode}.
*/
@Override
@Nullable
public final T getValue(Node node) {
public final @Nullable T getValue(Node node) {
assert node instanceof SimpleNode;
String key = node.getKey();
if (key == null)
Expand All @@ -40,8 +39,7 @@ public final T getValue(Node node) {
* @param value The String value to parse.
* @return The parsed value.
*/
@Nullable
protected abstract T getValue(String value);
protected abstract @Nullable T getValue(String value);

/**
* @return The String acting as a separator between the key and the value.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package org.skriptlang.skript.lang.entry.util;

import ch.njol.skript.lang.VariableString;
import ch.njol.skript.lang.parser.ParserInstance;
import org.skriptlang.skript.lang.entry.KeyValueEntryData;
import ch.njol.skript.util.StringMode;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.entry.KeyValueEntryData;

/**
* A type of {@link KeyValueEntryData} designed to parse its value as a {@link VariableString}.
Expand Down Expand Up @@ -40,8 +37,7 @@ public VariableStringEntryData(
}

@Override
@Nullable
protected VariableString getValue(String value) {
protected @Nullable VariableString getValue(String value) {
// Double up quotations outside of expressions
if (stringMode != StringMode.VARIABLE_NAME)
value = VariableString.quote(value);
Expand Down
14 changes: 14 additions & 0 deletions src/test/skript/junit/StructTestSubValidators.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
options:
test: "org.skriptlang.skript.test.tests.syntaxes.events.StructTestSubValidators"

test "StructTestSubValidators" when running JUnit:
ensure junit test {@test} completes "sub section" and "sub sub section"

test sub validators:
sub validator 1:
sub section:
complete objective "sub section" for {@test}
sub validator 2:
sub sub validator:
sub sub section:
complete objective "sub sub section" for {@test}