Skip to content

Commit 83198b1

Browse files
authored
Allow Literals in 'Size of' (#7961)
1 parent 95f2c75 commit 83198b1

File tree

2 files changed

+50
-32
lines changed

2 files changed

+50
-32
lines changed

src/main/java/ch/njol/skript/expressions/ExprAmount.java

Lines changed: 37 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,12 @@
22

33
import ch.njol.skript.Skript;
44
import ch.njol.skript.classes.Changer.ChangeMode;
5-
import ch.njol.skript.doc.Description;
6-
import ch.njol.skript.doc.Examples;
7-
import ch.njol.skript.doc.Name;
8-
import ch.njol.skript.doc.Since;
9-
import ch.njol.skript.lang.Expression;
10-
import ch.njol.skript.lang.ExpressionList;
11-
import ch.njol.skript.lang.ExpressionType;
12-
import ch.njol.skript.lang.Literal;
5+
import ch.njol.skript.doc.*;
6+
import ch.njol.skript.lang.*;
137
import ch.njol.skript.lang.SkriptParser.ParseResult;
14-
import ch.njol.skript.lang.Variable;
158
import ch.njol.skript.lang.util.SimpleExpression;
169
import ch.njol.skript.lang.util.common.AnyAmount;
10+
import ch.njol.skript.util.LiteralUtils;
1711
import ch.njol.util.Kleenean;
1812
import ch.njol.util.coll.CollectionUtils;
1913
import org.bukkit.event.Event;
@@ -39,7 +33,7 @@
3933
"",
4034
"Where using %size of {list::*}% will only return 3 (the first layer of indices only), while %recursive size of {list::*}% will return 6 (the entire list)",
4135
"Please note that getting a list's recursive size can cause lag if the list is large, so only use this expression if you need to!"})
42-
@Examples({"message \"There are %number of all players% players online!\""})
36+
@Example("message \"There are %number of all players% players online!\"")
4337
@Since("1.0")
4438
public class ExprAmount extends SimpleExpression<Number> {
4539

@@ -63,40 +57,47 @@ public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelaye
6357
this.any = (Expression<AnyAmount>) exprs[0];
6458
return true;
6559
}
66-
this.exprs = exprs[0] instanceof ExpressionList ? (ExpressionList<?>) exprs[0] : new ExpressionList<>(new Expression<?>[]{exprs[0]}, Object.class, false);
60+
61+
this.exprs = exprs[0] instanceof ExpressionList<?> exprList
62+
? exprList
63+
: new ExpressionList<>(new Expression<?>[]{ exprs[0] }, Object.class, false);
64+
65+
this.exprs = (ExpressionList<?>) LiteralUtils.defendExpression(this.exprs);
66+
if (!LiteralUtils.canInitSafely(this.exprs)) {
67+
return false;
68+
}
69+
70+
if (this.exprs.isSingle()) {
71+
Skript.error("'" + this.exprs.toString(null, Skript.debug()) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value.");
72+
return false;
73+
}
74+
6775
this.recursive = matchedPattern == 2;
6876
for (Expression<?> expr : this.exprs.getExpressions()) {
69-
if (expr instanceof Literal<?>) {
70-
return false;
71-
}
72-
if (expr.isSingle()) {
73-
Skript.error("'" + expr.toString(null, false) + "' can only ever have one value at most, thus the 'amount of ...' expression is useless. Use '... exists' instead to find out whether the expression has a value.");
74-
return false;
75-
}
7677
if (recursive && !(expr instanceof Variable<?>)) {
77-
Skript.error("Getting the recursive size of a list only applies to variables, thus the '" + expr.toString(null, false) + "' expression is useless.");
78+
Skript.error("Getting the recursive size of a list only applies to variables, thus the '" + expr.toString(null, Skript.debug()) + "' expression is useless.");
7879
return false;
7980
}
8081
}
8182
return true;
8283
}
8384

8485
@Override
85-
@SuppressWarnings("unchecked")
86-
protected Number[] get(Event e) {
86+
protected Number[] get(Event event) {
8787
if (any != null)
88-
return new Number[] {any.getOptionalSingle(e).orElse(() -> 0).amount()};
88+
return new Number[] {any.getOptionalSingle(event).orElse(() -> 0).amount()};
8989
if (recursive) {
9090
int currentSize = 0;
9191
for (Expression<?> expr : exprs.getExpressions()) {
92-
Object var = ((Variable<?>) expr).getRaw(e);
92+
Object var = ((Variable<?>) expr).getRaw(event);
9393
if (var != null) { // Should already be a map
94+
// noinspection unchecked
9495
currentSize += getRecursiveSize((Map<String, ?>) var);
9596
}
9697
}
9798
return new Long[]{(long) currentSize};
9899
}
99-
return new Long[]{(long) exprs.getArray(e).length};
100+
return new Long[]{(long) exprs.getArray(event).length};
100101
}
101102

102103
@Override
@@ -111,7 +112,7 @@ protected Number[] get(Event e) {
111112
}
112113

113114
@Override
114-
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
115+
public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
115116
if (any == null) {
116117
super.change(event, delta, mode);
117118
return;
@@ -138,13 +139,19 @@ public void change(Event event, Object @Nullable [] delta, ChangeMode mode) {
138139
}
139140
}
140141

141-
@SuppressWarnings("unchecked")
142-
private static int getRecursiveSize(Map<String, ?> map) {
142+
private static int getRecursiveSize(Map<?, ?> map) {
143+
return getRecursiveSize(map, true);
144+
}
145+
146+
private static int getRecursiveSize(Map<?, ?> map, boolean skipNull) {
143147
int count = 0;
144-
for (Map.Entry<String, ?> entry : map.entrySet()) {
148+
for (Map.Entry<?, ?> entry : map.entrySet()) {
149+
if (skipNull && entry.getKey() == null)
150+
continue; // when getting the recursive size of {a::*}, ignore {a}
151+
145152
Object value = entry.getValue();
146-
if (value instanceof Map)
147-
count += getRecursiveSize((Map<String, ?>) value);
153+
if (value instanceof Map<?, ?> nestedMap)
154+
count += getRecursiveSize(nestedMap, false);
148155
else
149156
count++;
150157
}
Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,23 @@
11
test "amount of objects":
22
set {_objects::*} to (1 and 2)
33
set {_amount} to amount of {_objects::*}
4-
assert {_amount} is 2 with "was wrong"
4+
assert {_amount} is 2 with "size of list was wrong - 1"
5+
56
set {_objects::*} to ("hello", "there" and 1)
67
set {_amount} to amount of {_objects::*}
7-
assert {_amount} is 3 with "was wrong"
8+
assert {_amount} is 3 with "size of list was wrong - 2"
9+
10+
assert size of (1, 2 and 3) is 3 with "size of literal list was wrong"
11+
assert size of (1, {_objects::*} and 3) is 5 with "size of mixed list was wrong"
812

913
test "amount of items":
1014
assert amount of (3 of stone) is 3 with "was wrong"
1115
set {_item} to 3 of stone
1216
assert amount of {_item} is 3 with "was wrong"
17+
18+
test "recursive size":
19+
set {_a} to 1
20+
set {_a::*} to 1, 2 and 3
21+
set {_a::1::*} to 1 and 2
22+
set {_a::1::1::1::1::1} to 5
23+
assert recursive size of {_a::*} is 6 with "recursive size was wrong"

0 commit comments

Comments
 (0)