Support MethodHandle function invocation with varargs array in SpEL
Prior to this commit, the Spring Expression Language (SpEL) could not invoke a varargs MethodHandle function with an array containing the variable arguments, although that is supported for a varargs Method function. Attempting to do so resulted in the array being supplied as a single argument to the MethodHandle. This commit addresses this by updating the executeFunctionViaMethodHandle(...) method in FunctionReference as follows when the user supplies the varargs already packaged in an array. - Creates a new array large enough to hold the non-varargs arguments and the unpackaged varargs arguments. - Adds the non-varargs arguments to the beginning of that array and adds the unpackaged varargs arguments to the end of that array. - Invokes the MethodHandle with the new arguments array. Closes gh-33191
This commit is contained in:
@@ -16,7 +16,6 @@
|
||||
|
||||
package org.springframework.expression.spel;
|
||||
|
||||
import org.junit.jupiter.api.Disabled;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import org.springframework.expression.spel.standard.SpelExpressionParser;
|
||||
@@ -106,22 +105,6 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
||||
evaluate("#varargsFunction2(9,'a',null,'b')", "9-[a, null, b]", String.class);
|
||||
}
|
||||
|
||||
@Disabled("Disabled until bugs are reported and fixed")
|
||||
@Test
|
||||
void functionWithVarargsViaMethodHandle_CurrentlyFailing() {
|
||||
// Calling 'public static String formatObjectVarargs(String format, Object... args)' -> String.format(format, args)
|
||||
|
||||
// No conversion necessary
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{''})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{''})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{' '})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{' '})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{'a'})", "x -> a", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{'a'})", "x -> a", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', new Object[]{'a', 'b', 'c'})", "x -> a b c", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', new String[]{'a', 'b', 'c'})", "x -> a b c", String.class);
|
||||
}
|
||||
|
||||
@Test // gh-33013
|
||||
void functionWithVarargsViaMethodHandle() {
|
||||
// Calling 'public static String formatObjectVarargs(String format, Object... args)' -> String.format(format, args)
|
||||
@@ -138,6 +121,14 @@ class VariableAndFunctionTests extends AbstractExpressionTests {
|
||||
evaluate("#formatObjectVarargs('x -> %s', ' ')", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', 'a')", "x -> a", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', 'a', 'b', 'c')", "x -> a b c", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{''})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{''})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{' '})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{' '})", "x -> ", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new Object[]{'a'})", "x -> a", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s', new String[]{'a'})", "x -> a", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', new Object[]{'a', 'b', 'c'})", "x -> a b c", String.class);
|
||||
evaluate("#formatObjectVarargs('x -> %s %s %s', new String[]{'a', 'b', 'c'})", "x -> a b c", String.class);
|
||||
|
||||
// Conversion necessary
|
||||
evaluate("#add('2', 5.0)", 7, Integer.class);
|
||||
|
||||
Reference in New Issue
Block a user