Skip to content

Commit

Permalink
Export behaviour from SecLoop instead.
Browse files Browse the repository at this point in the history
  • Loading branch information
Moderocky committed Apr 13, 2024
1 parent 6513ec2 commit 34f7505
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 46 deletions.
54 changes: 14 additions & 40 deletions src/main/java/ch/njol/skript/sections/SecFor.java
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@ public class SecFor extends SecLoop {
}

private @Nullable Expression<?> keyStore, valueStore;
private boolean isVariable;

@Override
@SuppressWarnings("unchecked")
Expand All @@ -104,7 +103,6 @@ public boolean init(Expression<?>[] exprs,
this.valueStore = exprs[1];
this.expression = LiteralUtils.defendExpression(exprs[2]);
}
this.isVariable = expression instanceof Variable;
//</editor-fold>
//<editor-fold desc="Check our input expressions are safe/correct" defaultstate="collapsed">
if (!(keyStore instanceof Variable || keyStore == null)) {
Expand Down Expand Up @@ -136,46 +134,22 @@ public boolean init(Expression<?>[] exprs,
}

@Override
@Nullable
protected TriggerItem walk(Event event) {
//<editor-fold desc="Get the iterator (duplicate of SecLoop)" defaultstate="collapsed">
Iterator<?> iter = super.iteratorMap.get(event);
if (iter == null) {
iter = this.isVariable
? ((Variable<?>) super.expression).variablesIterator(event)
: super.expression.iterator(event);
if (iter != null) {
if (iter.hasNext())
super.iteratorMap.put(event, iter);
else
iter = null;
}
}
//</editor-fold>
if (iter == null || !iter.hasNext()) {
this.exit(event);
this.debug(event, false);
return actualNext;
protected void store(Event event, Object next) {
super.store(event, next);
//<editor-fold desc="Store the loop index/value in the variables" defaultstate="collapsed">
if (next instanceof Map.Entry) {
@SuppressWarnings("unchecked") Map.Entry<String, Object> entry = (Map.Entry<String, Object>) next;
if (keyStore != null)
this.keyStore.change(event, new Object[]{entry.getKey()}, Changer.ChangeMode.SET);
if (valueStore != null)
this.valueStore.change(event, new Object[]{entry.getValue()}, Changer.ChangeMode.SET);
} else {
Object next = iter.next();
super.current.put(event, next);
super.currentLoopCounter.put(event, (currentLoopCounter.getOrDefault(event, 0L)) + 1);
//<editor-fold desc="Store the loop index/value in the variables" defaultstate="collapsed">
if (next instanceof Map.Entry) {
@SuppressWarnings("unchecked") Map.Entry<String, Object> entry = (Map.Entry<String, Object>) next;
if (keyStore != null)
this.keyStore.change(event, new Object[]{entry.getKey()}, Changer.ChangeMode.SET);
if (valueStore != null)
this.valueStore.change(event, new Object[]{entry.getValue()}, Changer.ChangeMode.SET);
} else {
if (keyStore != null)
this.keyStore.change(event, new Object[]{this.getLoopCounter(event)}, Changer.ChangeMode.SET);
if (valueStore != null)
this.valueStore.change(event, new Object[]{next}, Changer.ChangeMode.SET);
}
//</editor-fold>
return this.walk(event, true);
if (keyStore != null)
this.keyStore.change(event, new Object[]{this.getLoopCounter(event)}, Changer.ChangeMode.SET);
if (valueStore != null)
this.valueStore.change(event, new Object[]{next}, Changer.ChangeMode.SET);
}
//</editor-fold>
}

@Override
Expand Down
17 changes: 11 additions & 6 deletions src/main/java/ch/njol/skript/sections/SecLoop.java
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ public class SecLoop extends LoopSection {

protected @UnknownNullability Expression<?> expression;

protected final transient Map<Event, Object> current = new WeakHashMap<>();
protected final transient Map<Event, Iterator<?>> iteratorMap = new WeakHashMap<>();
private final transient Map<Event, Object> current = new WeakHashMap<>();
private final transient Map<Event, Iterator<?>> iteratorMap = new WeakHashMap<>();

@Nullable
protected TriggerItem actualNext;
Expand All @@ -103,7 +103,7 @@ public boolean init(Expression<?>[] exprs,
ParseResult parseResult,
SectionNode sectionNode,
List<TriggerItem> triggerItems) {
expression = LiteralUtils.defendExpression(exprs[0]);
this.expression = LiteralUtils.defendExpression(exprs[0]);
if (!LiteralUtils.canInitSafely(expression)) {
Skript.error("Can't understand this loop: '" + parseResult.expr.substring(5) + "'");
return false;
Expand All @@ -113,7 +113,7 @@ public boolean init(Expression<?>[] exprs,
ContainerType type = expression.getReturnType().getAnnotation(ContainerType.class);
if (type == null)
throw new SkriptAPIException(expression.getReturnType().getName() + " implements Container but is missing the required @ContainerType annotation");
expression = new ContainerExpression((Expression<? extends Container<?>>) expression, type.value());
this.expression = new ContainerExpression((Expression<? extends Container<?>>) expression, type.value());
}

if (expression.isSingle()) {
Expand Down Expand Up @@ -145,12 +145,17 @@ protected TriggerItem walk(Event event) {
debug(event, false);
return actualNext;
} else {
current.put(event, iter.next());
currentLoopCounter.put(event, (currentLoopCounter.getOrDefault(event, 0L)) + 1);
Object next = iter.next();
this.store(event, next);
return walk(event, true);
}
}

protected void store(Event event, Object next) {
this.current.put(event, next);
this.currentLoopCounter.put(event, (currentLoopCounter.getOrDefault(event, 0L)) + 1);
}

@Override
public String toString(@Nullable Event event, boolean debug) {
return "loop " + expression.toString(event, debug);
Expand Down
49 changes: 49 additions & 0 deletions src/test/skript/tests/syntaxes/sections/SecFor.sk
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
using for each loops

test "for section":

set {_list::*} to 1, 5, and 10
set {_expect} to 0
for {_value} in {_list::*}:
assert {_value} is greater than 0 with "Expected value > 0, found %{_value}%"
set {_expect} to {_value}

assert {_value} is 10 with "Expected value = 10, found %{_value}%"
assert {_expect} is 10 with "Expected expect = 10, found %{_expect}%"

delete {_key}
delete {_value}

for {_key} = {_value} in {_list::*}:
assert {_key} is greater than 0 with "Expected key > 0, found %{_key}%"
assert {_key} is less than 4 with "Expected key < 4, found %{_key}%"
assert {_value} is greater than 0 with "Expected value > 0, found %{_value}%"

assert {_key} is 3 with "Expected key = 3, found %{_key}%"
assert {_value} is 10 with "Expected value = 10, found %{_value}%"

delete {_key}
delete {_value}


for key {_key} and value {_value} in {_list::*}:
assert {_key} is greater than 0 with "Expected key > 0, found %{_key}%"
assert {_key} is less than 4 with "Expected key < 4, found %{_key}%"
assert {_value} is greater than 0 with "Expected value > 0, found %{_value}%"

assert {_key} is 3 with "Expected key = 3, found %{_key}%"
assert {_value} is 10 with "Expected value = 10, found %{_value}%"

delete {_key}
delete {_value}

for {_key} and {_value} in {_list::*}:
assert {_key} is greater than 0 with "Expected key > 0, found %{_key}%"
assert {_key} is less than 4 with "Expected key < 4, found %{_key}%"
assert {_value} is greater than 0 with "Expected value > 0, found %{_value}%"

assert {_key} is 3 with "Expected key = 3, found %{_key}%"
assert {_value} is 10 with "Expected value = 10, found %{_value}%"

delete {_key}
delete {_value}

0 comments on commit 34f7505

Please sign in to comment.