Skip to content

Commit 94a68fb

Browse files
authored
Function overloading fixes and improvements (#8032)
* init * fix single list value functions, clamp * fix dynamic functions * update docs * reviews * skript parser strikes again * enjoy your holiday pickle * fix checkstyle
1 parent 7dad407 commit 94a68fb

File tree

8 files changed

+115
-112
lines changed

8 files changed

+115
-112
lines changed

src/main/java/ch/njol/skript/lang/SkriptParser.java

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1124,20 +1124,8 @@ private SkriptParser suppressMissingAndOrWarnings() {
11241124
ParserInstance parser = getParser();
11251125
Script currentScript = parser.isActive() ? parser.getCurrentScript() : null;
11261126
FunctionReference<T> functionReference = new FunctionReference<>(functionName, SkriptLogger.getNode(),
1127-
currentScript != null ? currentScript.getConfig().getFileName() : null, types, params);//.toArray(new Expression[params.size()]));
1128-
attempt_list_parse:
1129-
if (unaryArgument.get() && !functionReference.validateParameterArity(true)) {
1130-
try (ParseLogHandler ignored = SkriptLogger.startParseLogHandler()) {
1131-
SkriptParser alternative = new SkriptParser(args, flags | PARSE_LITERALS, context);
1132-
params = this.getFunctionArguments(() -> alternative.suppressMissingAndOrWarnings()
1133-
.parseExpressionList(ignored, Object.class), args, unaryArgument);
1134-
ignored.clear();
1135-
if (params == null)
1136-
break attempt_list_parse;
1137-
}
1138-
functionReference = new FunctionReference<>(functionName, SkriptLogger.getNode(),
1139-
currentScript != null ? currentScript.getConfig().getFileName() : null, types, params);
1140-
}
1127+
currentScript != null ? currentScript.getConfig().getFileName() : null, types, params);
1128+
11411129
if (!functionReference.validateFunction(true)) {
11421130
log.printError();
11431131
return null;

src/main/java/ch/njol/skript/lang/function/DynamicFunctionReference.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package ch.njol.skript.lang.function;
22

33
import ch.njol.skript.ScriptLoader;
4-
import ch.njol.skript.Skript;
54
import ch.njol.skript.lang.Expression;
65
import ch.njol.skript.lang.ExpressionList;
76
import ch.njol.skript.lang.util.common.AnyNamed;
@@ -60,10 +59,10 @@ public DynamicFunctionReference(@NotNull String name, @Nullable Script source) {
6059
// will return the first function found that matches name.
6160
// TODO: add a way to specify param types
6261
//noinspection unchecked
63-
function = (Function<? extends Result>) FunctionRegistry.getRegistry().getFunction(source.getConfig().getFileName(), name).retrieved();
62+
function = (Function<? extends Result>) Functions.getFunction(name, source.getConfig().getFileName());
6463
} else {
6564
//noinspection unchecked
66-
function = (Function<? extends Result>) FunctionRegistry.getRegistry().getFunction(null, name).retrieved();
65+
function = (Function<? extends Result>) Functions.getFunction(name, null);
6766
}
6867

6968
this.resolved = function != null;

src/main/java/ch/njol/skript/lang/function/FunctionReference.java

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import org.jetbrains.annotations.Nullable;
2121
import org.skriptlang.skript.lang.converter.Converters;
2222
import org.skriptlang.skript.util.Executable;
23+
2324
import java.util.*;
2425
import java.util.stream.Collectors;
2526

@@ -133,12 +134,24 @@ public boolean validateFunction(boolean first) {
133134
Skript.debug("Validating function " + functionName);
134135
Signature<?> sign = getRegisteredSignature();
135136

137+
StringJoiner args = new StringJoiner(", ");
138+
for (Class<?> parameterType : parameterTypes) {
139+
Class<?> searchType;
140+
if (parameterType.isArray()) {
141+
searchType = parameterType.componentType();
142+
} else {
143+
searchType = parameterType;
144+
}
145+
args.add(Classes.getSuperClassInfo(searchType).getCodeName());
146+
}
147+
String stringified = "%s(%s)".formatted(functionName, args);
148+
136149
// Check if the requested function exists
137150
if (sign == null) {
138151
if (first) {
139-
Skript.error("The function '" + functionName + "' does not exist.");
152+
Skript.error("The function '" + stringified + "' does not exist.");
140153
} else {
141-
Skript.error("The function '" + functionName + "' was deleted or renamed, but is still used in other script(s)."
154+
Skript.error("The function '" + stringified + "' was deleted or renamed, but is still used in other script(s)."
142155
+ " These will continue to use the old version of the function until Skript restarts.");
143156
function = previousFunction;
144157
}
@@ -151,19 +164,19 @@ public boolean validateFunction(boolean first) {
151164
ClassInfo<?> rt = sign.returnType;
152165
if (rt == null) {
153166
if (first) {
154-
Skript.error("The function '" + functionName + "' doesn't return any value.");
167+
Skript.error("The function '" + stringified + "' doesn't return any value.");
155168
} else {
156-
Skript.error("The function '" + functionName + "' was redefined with no return value, but is still used in other script(s)."
169+
Skript.error("The function '" + stringified + "' was redefined with no return value, but is still used in other script(s)."
157170
+ " These will continue to use the old version of the function until Skript restarts.");
158171
function = previousFunction;
159172
}
160173
return false;
161174
}
162175
if (!Converters.converterExists(rt.getC(), returnTypes)) {
163176
if (first) {
164-
Skript.error("The returned value of the function '" + functionName + "', " + sign.returnType + ", is " + SkriptParser.notOfType(returnTypes) + ".");
177+
Skript.error("The returned value of the function '" + stringified + "', " + sign.returnType + ", is " + SkriptParser.notOfType(returnTypes) + ".");
165178
} else {
166-
Skript.error("The function '" + functionName + "' was redefined with a different, incompatible return type, but is still used in other script(s)."
179+
Skript.error("The function '" + stringified + "' was redefined with a different, incompatible return type, but is still used in other script(s)."
167180
+ " These will continue to use the old version of the function until Skript restarts.");
168181
function = previousFunction;
169182
}
@@ -186,15 +199,15 @@ public boolean validateFunction(boolean first) {
186199
if (parameters.length > sign.getMaxParameters()) {
187200
if (first) {
188201
if (sign.getMaxParameters() == 0) {
189-
Skript.error("The function '" + functionName + "' has no arguments, but " + parameters.length + " are given."
202+
Skript.error("The function '" + stringified + "' has no arguments, but " + parameters.length + " are given."
190203
+ " To call a function without parameters, just write the function name followed by '()', e.g. 'func()'.");
191204
} else {
192-
Skript.error("The function '" + functionName + "' has only " + sign.getMaxParameters() + " argument" + (sign.getMaxParameters() == 1 ? "" : "s") + ","
205+
Skript.error("The function '" + stringified + "' has only " + sign.getMaxParameters() + " argument" + (sign.getMaxParameters() == 1 ? "" : "s") + ","
193206
+ " but " + parameters.length + " are given."
194207
+ " If you want to use lists in function calls, you have to use additional parentheses, e.g. 'give(player, (iron ore and gold ore))'");
195208
}
196209
} else {
197-
Skript.error("The function '" + functionName + "' was redefined with a different, incompatible amount of arguments, but is still used in other script(s)."
210+
Skript.error("The function '" + stringified + "' was redefined with a different, incompatible amount of arguments, but is still used in other script(s)."
198211
+ " These will continue to use the old version of the function until Skript restarts.");
199212
function = previousFunction;
200213
}
@@ -205,10 +218,10 @@ public boolean validateFunction(boolean first) {
205218
// Not enough parameters
206219
if (parameters.length < sign.getMinParameters()) {
207220
if (first) {
208-
Skript.error("The function '" + functionName + "' requires at least " + sign.getMinParameters() + " argument" + (sign.getMinParameters() == 1 ? "" : "s") + ","
221+
Skript.error("The function '" + stringified + "' requires at least " + sign.getMinParameters() + " argument" + (sign.getMinParameters() == 1 ? "" : "s") + ","
209222
+ " but only " + parameters.length + " " + (parameters.length == 1 ? "is" : "are") + " given.");
210223
} else {
211-
Skript.error("The function '" + functionName + "' was redefined with a different, incompatible amount of arguments, but is still used in other script(s)."
224+
Skript.error("The function '" + stringified + "' was redefined with a different, incompatible amount of arguments, but is still used in other script(s)."
212225
+ " These will continue to use the old version of the function until Skript restarts.");
213226
function = previousFunction;
214227
}
@@ -227,12 +240,12 @@ public boolean validateFunction(boolean first) {
227240
if (LiteralUtils.hasUnparsedLiteral(parameters[i])) {
228241
Skript.error("Can't understand this expression: " + parameters[i].toString());
229242
} else {
230-
Skript.error("The " + StringUtils.fancyOrderNumber(i + 1) + " argument given to the function '" + functionName + "' is not of the required type " + p.type + "."
243+
Skript.error("The " + StringUtils.fancyOrderNumber(i + 1) + " argument given to the function '" + stringified + "' is not of the required type " + p.type + "."
231244
+ " Check the correct order of the arguments and put lists into parentheses if appropriate (e.g. 'give(player, (iron ore and gold ore))')."
232245
+ " Please note that storing the value in a variable and then using that variable as parameter may suppress this error, but it still won't work.");
233246
}
234247
} else {
235-
Skript.error("The function '" + functionName + "' was redefined with different, incompatible arguments, but is still used in other script(s)."
248+
Skript.error("The function '" + stringified + "' was redefined with different, incompatible arguments, but is still used in other script(s)."
236249
+ " These will continue to use the old version of the function until Skript restarts.");
237250
function = previousFunction;
238251
}
@@ -242,7 +255,7 @@ public boolean validateFunction(boolean first) {
242255
Skript.error("The " + StringUtils.fancyOrderNumber(i + 1) + " argument given to the function '" + functionName + "' is plural, "
243256
+ "but a single argument was expected");
244257
} else {
245-
Skript.error("The function '" + functionName + "' was redefined with different, incompatible arguments, but is still used in other script(s)."
258+
Skript.error("The function '" + stringified + "' was redefined with different, incompatible arguments, but is still used in other script(s)."
246259
+ " These will continue to use the old version of the function until Skript restarts.");
247260
function = previousFunction;
248261
}
@@ -294,13 +307,6 @@ private Signature<?> getRegisteredSignature() {
294307
return attempt.retrieved();
295308
}
296309

297-
// if we can't find a signature based on param types, try to match any function
298-
attempt = FunctionRegistry.getRegistry().getSignature(script, functionName);
299-
300-
if (attempt.result() == RetrievalResult.EXACT) {
301-
return attempt.retrieved();
302-
}
303-
304310
if (attempt.result() == RetrievalResult.AMBIGUOUS) {
305311
ambiguousError(attempt.conflictingArgs());
306312
}
@@ -325,13 +331,6 @@ private Function<?> getRegisteredFunction() {
325331
return attempt.retrieved();
326332
}
327333

328-
// if we can't find a signature based on param types, try to match any function
329-
attempt = FunctionRegistry.getRegistry().getFunction(script, functionName);
330-
331-
if (attempt.result() == RetrievalResult.EXACT) {
332-
return attempt.retrieved();
333-
}
334-
335334
if (attempt.result() == RetrievalResult.AMBIGUOUS) {
336335
ambiguousError(attempt.conflictingArgs());
337336
}

0 commit comments

Comments
 (0)