Skip to content

Commit

Permalink
Fix function converters and plural arguments when single expected (Sk…
Browse files Browse the repository at this point in the history
…riptLang#4896)

* Make functions error for incorrect argument plurality (single expected, multiple provided)
  • Loading branch information
TPGamesNL authored Jul 18, 2022
1 parent 70df50b commit baccca9
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 25 deletions.
47 changes: 24 additions & 23 deletions src/main/java/ch/njol/skript/lang/function/ExprFunctionCall.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,54 +18,55 @@
*/
package ch.njol.skript.lang.function;

import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

import ch.njol.skript.lang.Expression;
import ch.njol.skript.lang.SkriptParser.ParseResult;
import ch.njol.skript.lang.util.SimpleExpression;
import ch.njol.skript.registrations.Converters;
import ch.njol.skript.util.Utils;
import ch.njol.util.Kleenean;
import org.bukkit.event.Event;
import org.eclipse.jdt.annotation.Nullable;

/**
* @author Peter Güttinger
*/
public class ExprFunctionCall<T> extends SimpleExpression<T> {

private final FunctionReference<T> function;

public ExprFunctionCall(final FunctionReference<T> function) {
private final FunctionReference<?> function;
private final Class<? extends T>[] returnTypes;
private final Class<T> returnType;

@SuppressWarnings("unchecked")
public ExprFunctionCall(FunctionReference<T> function) {
this.function = function;
this.returnTypes = function.returnTypes;
this.returnType = (Class<T>) Utils.getSuperType(returnTypes);
}

@Override
@Nullable
protected T[] get(final Event e) {
T[] returnValue = function.execute(e);
protected T[] get(Event e) {
Object[] returnValue = function.execute(e);
function.resetReturnValue();
return returnValue;
return Converters.convertArray(returnValue, returnTypes, returnType);
}

@Override
public boolean isSingle() {
return function.isSingle();
}

@Override
public Class<? extends T> getReturnType() {
Class<? extends T> type = function.getReturnType();
assert type != null : "validateFunction() let invalid reference pass";
return type;
return returnType;
}

@Override
public String toString(@Nullable final Event e, final boolean debug) {
public String toString(@Nullable Event e, boolean debug) {
return function.toString(e, debug);
}

@Override
public boolean init(final Expression<?>[] exprs, final int matchedPattern, final Kleenean isDelayed, final ParseResult parseResult) {
public boolean init(Expression<?>[] exprs, int matchedPattern, Kleenean isDelayed, ParseResult parseResult) {
assert false;
return false;
}

}
15 changes: 13 additions & 2 deletions src/main/java/ch/njol/skript/lang/function/FunctionReference.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import ch.njol.skript.log.RetainingLogHandler;
import ch.njol.skript.log.SkriptLogger;
import ch.njol.skript.registrations.Classes;
import ch.njol.skript.registrations.Converters;
import ch.njol.skript.util.LiteralUtils;
import ch.njol.util.StringUtils;
import ch.njol.util.coll.CollectionUtils;
Expand Down Expand Up @@ -84,7 +85,7 @@ public class FunctionReference<T> {
* of the function signature.
*/
@Nullable
private final Class<? extends T>[] returnTypes;
final Class<? extends T>[] returnTypes;

/**
* Node for {@link #validateFunction(boolean)} to use for logging.
Expand Down Expand Up @@ -147,7 +148,7 @@ public boolean validateFunction(boolean first) {
}
return false;
}
if (!CollectionUtils.containsAnySuperclass(returnTypes, rt.getC())) {
if (!Converters.converterExists(rt.getC(), returnTypes)) {
if (first) {
Skript.error("The returned value of the function '" + functionName + "', " + sign.returnType + ", is " + SkriptParser.notOfType(returnTypes) + ".");
} else {
Expand Down Expand Up @@ -224,6 +225,16 @@ public boolean validateFunction(boolean first) {
function = previousFunction;
}
return false;
} else if (p.single && !e.isSingle()) {
if (first) {
Skript.error("The " + StringUtils.fancyOrderNumber(i + 1) + " argument given to the function '" + functionName + "' is plural, "
+ "but a single argument was expected");
} else {
Skript.error("The function '" + functionName + "' was redefined with different, incompatible arguments, but is still used in other script(s)."
+ " These will continue to use the old version of the function until Skript restarts.");
function = previousFunction;
}
return false;
}
parameters[i] = e;
} finally {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function functionCallConversion() :: item:
return stone named "abc"

test "function call conversion":
assert name of functionCallConversion() is "abc" with "Name of item from function call failed"
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
function pluralArgSingleParam(a: string, b: number) :: number:
return 1

test "function error with plural argument for single parameter":
assert pluralArgSingleParam(("abc", "def"), 1) is 1 to fail with "function call didn't error with plural argument when single expected"

0 comments on commit baccca9

Please sign in to comment.