diff --git a/src/main/java/ch/njol/skript/sections/SecFor.java b/src/main/java/ch/njol/skript/sections/SecFor.java index b4d99b95584..e2b506e866d 100644 --- a/src/main/java/ch/njol/skript/sections/SecFor.java +++ b/src/main/java/ch/njol/skript/sections/SecFor.java @@ -77,7 +77,6 @@ public class SecFor extends SecLoop { } private @Nullable Expression keyStore, valueStore; - private boolean isVariable; @Override @SuppressWarnings("unchecked") @@ -104,7 +103,6 @@ public boolean init(Expression[] exprs, this.valueStore = exprs[1]; this.expression = LiteralUtils.defendExpression(exprs[2]); } - this.isVariable = expression instanceof Variable; // // if (!(keyStore instanceof Variable || keyStore == null)) { @@ -136,46 +134,22 @@ public boolean init(Expression[] exprs, } @Override - @Nullable - protected TriggerItem walk(Event event) { - // - 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; - } - } - // - 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); + // + if (next instanceof Map.Entry) { + @SuppressWarnings("unchecked") Map.Entry entry = (Map.Entry) 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); - // - if (next instanceof Map.Entry) { - @SuppressWarnings("unchecked") Map.Entry entry = (Map.Entry) 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); - } - // - 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); } + // } @Override diff --git a/src/main/java/ch/njol/skript/sections/SecLoop.java b/src/main/java/ch/njol/skript/sections/SecLoop.java index a753a513354..b955d33e0d4 100644 --- a/src/main/java/ch/njol/skript/sections/SecLoop.java +++ b/src/main/java/ch/njol/skript/sections/SecLoop.java @@ -89,8 +89,8 @@ public class SecLoop extends LoopSection { protected @UnknownNullability Expression expression; - protected final transient Map current = new WeakHashMap<>(); - protected final transient Map> iteratorMap = new WeakHashMap<>(); + private final transient Map current = new WeakHashMap<>(); + private final transient Map> iteratorMap = new WeakHashMap<>(); @Nullable protected TriggerItem actualNext; @@ -103,7 +103,7 @@ public boolean init(Expression[] exprs, ParseResult parseResult, SectionNode sectionNode, List 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; @@ -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>) expression, type.value()); + this.expression = new ContainerExpression((Expression>) expression, type.value()); } if (expression.isSingle()) { @@ -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); diff --git a/src/test/skript/tests/syntaxes/sections/SecFor.sk b/src/test/skript/tests/syntaxes/sections/SecFor.sk new file mode 100644 index 00000000000..e4ac211d5a3 --- /dev/null +++ b/src/test/skript/tests/syntaxes/sections/SecFor.sk @@ -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}