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
2 changes: 1 addition & 1 deletion src/main/java/ch/njol/skript/expressions/ExprFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public boolean canReturnKeys() {

@Override
public boolean areKeysRecommended() {
return false;
return KeyProviderExpression.areKeysRecommended(unfilteredObjects);
}

@Override
Expand Down
15 changes: 14 additions & 1 deletion src/main/java/ch/njol/skript/expressions/ExprIndices.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package ch.njol.skript.expressions;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.*;
import ch.njol.skript.doc.Description;
import ch.njol.skript.doc.Example;
import ch.njol.skript.doc.Name;
import ch.njol.skript.doc.Since;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.KeyProviderExpression;
Expand Down Expand Up @@ -93,6 +96,16 @@ public Class<? extends String> getReturnType() {
return String.class;
}

@Override
public boolean returnNestedStructures(boolean value) {
return keyedExpression.returnNestedStructures(true);
}

@Override
public boolean returnsNestedStructures() {
return keyedExpression.returnsNestedStructures();
}

@Override
public String toString(@Nullable Event e, boolean debug) {
String text = "indices of " + keyedExpression.toString(e, debug);
Expand Down
23 changes: 21 additions & 2 deletions src/main/java/ch/njol/skript/expressions/ExprKeyed.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.KeyProviderExpression;
import ch.njol.skript.lang.KeyedValue;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Iterator;

@Name("Keyed")
@Description({
"This expression is used to explicitly pass the keys of an expression alongside its values.",
Expand Down Expand Up @@ -69,12 +72,23 @@ public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean is

@Override
public @NotNull String @NotNull [] getArrayKeys(Event event) throws IllegalStateException {
return ((KeyProviderExpression<?>) getExpr()).getArrayKeys(event);
return getExpr().getArrayKeys(event);
}

@Override
public @NotNull String @NotNull [] getAllKeys(Event event) {
return ((KeyProviderExpression<?>) getExpr()).getAllKeys(event);
return getExpr().getAllKeys(event);
}

@Override
public Iterator<KeyedValue<Object>> keyedIterator(Event event) {
//noinspection unchecked,rawtypes
return (Iterator) getExpr().keyedIterator(event);
}

@Override
public boolean isIndexLoop(String input) {
return getExpr().isIndexLoop(input);
}

@Override
Expand All @@ -87,4 +101,9 @@ public String toString(@Nullable Event event, boolean debug) {
return "keyed " + getExpr().toString(event, debug);
}

@Override
public KeyProviderExpression<?> getExpr() {
return (KeyProviderExpression<?>) super.getExpr();
}

}
108 changes: 108 additions & 0 deletions src/main/java/ch/njol/skript/expressions/ExprRecursive.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package ch.njol.skript.expressions;

import ch.njol.skript.Skript;
import ch.njol.skript.doc.*;
import ch.njol.skript.expressions.base.WrapperExpression;
import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.ExpressionType;
import ch.njol.skript.lang.KeyProviderExpression;
import ch.njol.skript.lang.KeyedValue;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Iterator;

@Name("Recursive")
@Description("Returns all values of an expression, including those in nested structures such as lists of lists.")
@Example("""
on load:
set {_data::a::b::c} to "value1"
set {_data::a::b::d} to "value2"
set {_data::a::e} to "value3"
set {_data::f} to "value4"

broadcast recursive {_data::*}
# broadcasts "value1", "value2", "value3", "value4"

broadcast recursive indices of {_data::*}
# broadcasts "a::b::c", "a::b::d", "a::e", "f"
""")
@Since("INSERT VERSION")
@Keywords({"deep", "nested"})
public class ExprRecursive extends WrapperExpression<Object> implements KeyProviderExpression<Object> {

static {
Skript.registerExpression(ExprRecursive.class, Object.class, ExpressionType.COMBINED, "recursive %~objects%");
}

private boolean returnsKeys;

@Override
public boolean init(Expression<?>[] expressions, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
if (!expressions[0].returnNestedStructures(true)) {
Skript.error(expressions[0] + " does not support nested structures.");
return false;
}
setExpr(expressions[0]);
returnsKeys = KeyProviderExpression.canReturnKeys(getExpr());
return true;
}

@Override
public Object[] getAll(Event event) {
return getExpr().getAll(event);
}

@Override
public @NotNull String @NotNull [] getArrayKeys(Event event) throws IllegalStateException {
if (!returnsKeys)
throw new IllegalStateException();
return ((KeyProviderExpression<?>) getExpr()).getArrayKeys(event);
}

@Override
public @NotNull String @NotNull [] getAllKeys(Event event) {
if (!returnsKeys)
throw new IllegalStateException();
return ((KeyProviderExpression<?>) getExpr()).getAllKeys(event);
}

@Override
public Iterator<KeyedValue<Object>> keyedIterator(Event event) {
if (!returnsKeys)
throw new IllegalStateException();
//noinspection unchecked
return ((KeyProviderExpression<Object>) getExpr()).keyedIterator(event);
}

@Override
public boolean canReturnKeys() {
return returnsKeys;
}

@Override
public boolean areKeysRecommended() {
return KeyProviderExpression.areKeysRecommended(getExpr());
}

@Override
public boolean isIndexLoop(String input) {
if (!returnsKeys)
throw new IllegalStateException();
return ((KeyProviderExpression<?>) getExpr()).isIndexLoop(input);
}

@Override
public boolean isLoopOf(String input) {
return getExpr().isLoopOf(input);
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "recursive " + getExpr().toString(event, debug);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ public boolean canReturnKeys() {

@Override
public boolean areKeysRecommended() {
return false;
return KeyProviderExpression.areKeysRecommended(mappingExpr);
}

@Override
Expand Down
27 changes: 25 additions & 2 deletions src/main/java/ch/njol/skript/expressions/ExprValueWithin.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.util.ClassInfoReference;
import ch.njol.skript.util.Utils;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.Iterator;

@Name("Value Within")
@Description(
"Gets the value within objects. Usually used with variables to get the value they store rather than the variable itself, " +
Expand Down Expand Up @@ -81,14 +82,29 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
return ((KeyProviderExpression<?>) getExpr()).getArrayKeys(event);
}

@Override
public @NotNull String @NotNull [] getAllKeys(Event event) {
if (!returnsKeys)
throw new IllegalStateException();
return ((KeyProviderExpression<?>) getExpr()).getAllKeys(event);
}

@Override
public Iterator<KeyedValue<Object>> keyedIterator(Event event) {
if (!returnsKeys)
throw new IllegalStateException();
//noinspection unchecked
return ((KeyProviderExpression<Object>) getExpr()).keyedIterator(event);
}

@Override
public boolean canReturnKeys() {
return returnsKeys;
}

@Override
public boolean areKeysRecommended() {
return false;
return KeyProviderExpression.areKeysRecommended(getExpr());
}

@Override
Expand All @@ -107,6 +123,13 @@ public void change(Event event, @Nullable Object[] delta, ChangeMode mode) {
changer.change(getArray(event), delta, mode);
}

@Override
public boolean isIndexLoop(String input) {
if (!returnsKeys)
throw new IllegalStateException();
return ((KeyProviderExpression<?>) getExpr()).isIndexLoop(input);
}

@Override
public boolean isLoopOf(String input) {
return getExpr().isLoopOf(input);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,16 @@ public int getTime() {
return expr.getTime();
}

@Override
public boolean returnNestedStructures(boolean value) {
return expr.returnNestedStructures(true);
}

@Override
public boolean returnsNestedStructures() {
return expr.returnsNestedStructures();
}

@Override
public boolean isDefault() {
return expr.isDefault();
Expand Down
25 changes: 24 additions & 1 deletion src/main/java/ch/njol/skript/lang/Expression.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import ch.njol.skript.classes.Changer.ChangeMode;
import ch.njol.skript.classes.Changer.ChangerUtils;
import ch.njol.skript.conditions.CondIsSet;
import ch.njol.skript.lang.simplification.Simplifiable;
import ch.njol.skript.lang.util.ConvertedExpression;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.log.ErrorQuality;
Expand All @@ -16,7 +17,6 @@
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.skriptlang.skript.lang.converter.Converter;
import ch.njol.skript.lang.simplification.Simplifiable;

import java.util.*;
import java.util.function.Function;
Expand Down Expand Up @@ -239,6 +239,29 @@ default boolean canReturn(Class<?> returnType) {
*/
int getTime();

/**
* Allows the expression to return nested structures, i.e. lists of lists.
* <p>
* <b>Note</b>:
* Nested structures must be flattened in {@link #getArray(Event)} and {@link #getAll(Event)},
* i.e. if this expression returns a list of lists of players,
* {@link #getArray(Event)} must return a single array containing all players of all lists
*
* @return Whether this expression supports nested structures.
* @see #returnsNestedStructures()
*/
default boolean returnNestedStructures(boolean value) {
return false;
}

/**
* @return Whether this expression returns nested structures
* @see #returnNestedStructures(boolean)
*/
default boolean returnsNestedStructures() {
return false;
}

/**
* Returns whether this value represents the default value of its type for the event, i.e. it can be replaced with a call to event.getXyz() if one knows the event & value type.
* <p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
* {@link #getAllKeys(Event)}.</li>
* <li>{@link #getArrayKeys(Event)} might be called after the corresponding {@link #getArray(Event)}</li>
* <li>{@link #getAllKeys(Event)} might be called after the corresponding {@link #getAll(Event)}</li>
* <li>{@link #isLoopOf(String)} should be overridden to return {@code KeyProviderExpression.super.isLoopOf(input) || ...}</li>
* </ul>
* <br/>
* <h2>Advice on Caching</h2>
Expand Down Expand Up @@ -163,7 +164,6 @@ default boolean isLoopOf(String input) {
return canReturnKeys() && isIndexLoop(input);
}


/**
* Checks whether the 'loop-...' expression should match this loop's index,
* e.g. loop-index matches the index of a loop that iterates over a list variable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,15 @@
*/
public interface KeyReceiverExpression<T> extends Expression<T> {

/**
* Returns whether this expression's changer supports nested structures.
*
* @return true if nested structures are supported, false otherwise
*/
default boolean acceptsNestedStructures() {
return false;
}

/**
* An alternative changer method that provides a set of keys as well as a set of values.
* This is only ever called for {@link ChangeMode#supportsKeyedChange()} safe change modes,
Expand Down
Loading