Skip to content

Commit

Permalink
Qute generated value resolvers - fix varArgs methods with 1 argument
Browse files Browse the repository at this point in the history
- fixes #31449
  • Loading branch information
mkouba committed Feb 28, 2023
1 parent 042a965 commit ed1f03a
Show file tree
Hide file tree
Showing 2 changed files with 58 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.util.Arrays;

import jakarta.inject.Inject;
import jakarta.inject.Named;
import jakarta.inject.Singleton;

import org.jboss.shrinkwrap.api.asset.StringAsset;
import org.junit.jupiter.api.Test;
Expand All @@ -22,23 +26,38 @@ public class VarargsMethodTest {
.addAsResource(new StringAsset("{foo.getStr}:{foo.getStr('foo','bar','baz')}"),
"templates/foo.txt")
.addAsResource(new StringAsset("{fmt.format('a','b','c')}"),
"templates/bar.txt"));
"templates/bar.txt")
.addAsResource(new StringAsset("{foo.getInt}:{foo.getInt(1)}:{foo.getInt(1,2,3)}"),
"templates/baz.txt")
.addAsResource(
new StringAsset(
"{cdi:qux.getBoolean(1)}:{cdi:qux.getBoolean(1, true, false)}:{cdi:qux.getBoolean(2, false)}"),
"templates/qux.txt"));;

@Inject
Template foo;

@Inject
Template bar;

@Inject
Template baz;

@Inject
Template qux;

@Test
public void testVarargs() {
assertEquals("ok:foo:bar baz", foo.data("foo", new Foo()).render());
assertEquals(" b a", bar.data("fmt", "%2$2s%1$2s").render());
assertEquals("[]:[1]:[1, 2, 3]", baz.data("foo", new Foo()).render());
assertEquals("1 []:1 [true, false]:2 [false]", qux.render());
}

@TemplateData(properties = false)
public static class Foo {

// This one is ignored
String getStr(String foo) {
return foo;
}
Expand All @@ -52,11 +71,25 @@ public String getStr(String foo, String... args) {
return foo + String.format(":%s %s", args[0], args[1]);
}

public String getInt(int... args) {
return Arrays.toString(args);
}

@TemplateExtension
static String format(String fmt, Object... args) {
return String.format(fmt, args);
}

}

@Named
@Singleton
public static class Qux {

public String getBoolean(int first, Boolean... args) {
return first + " " + Arrays.toString(args);
}

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -690,21 +690,41 @@ private void matchMethod(MethodInfo method, ClassInfo clazz, MethodCreator resol
exception.invokeVirtualMethod(Descriptors.COMPLETABLE_FUTURE_COMPLETE_EXCEPTIONALLY, whenRet,
exception.getCaughtException());

ResultHandle[] realParamsHandle = paramsHandle;
if (isVarArgs(method)) {
// For varargs the number of results may be higher than the number of method params
// First get the regular params
realParamsHandle = new ResultHandle[parameterTypes.size()];
for (int i = 0; i < parameterTypes.size() - 1; i++) {
ResultHandle resultHandle = tryCatch.invokeVirtualMethod(Descriptors.EVALUATED_PARAMS_GET_RESULT,
whenEvaluatedParams, tryCatch.load(i));
realParamsHandle[i] = resultHandle;
}
// Then we need to create an array for the last argument
Type varargsParam = parameterTypes.get(parameterTypes.size() - 1);
ResultHandle componentType = tryCatch
.loadClass(varargsParam.asArrayType().component().name().toString());
ResultHandle varargsResults = tryCatch.invokeVirtualMethod(Descriptors.EVALUATED_PARAMS_GET_VARARGS_RESULTS,
evaluatedParams, tryCatch.load(parameterTypes.size()), componentType);
// E.g. String, String, String -> String, String[]
realParamsHandle[parameterTypes.size() - 1] = varargsResults;
}

if (Modifier.isStatic(method.flags())) {
if (Modifier.isInterface(clazz.flags())) {
tryCatch.assign(invokeRet,
tryCatch.invokeStaticInterfaceMethod(MethodDescriptor.of(method), paramsHandle));
tryCatch.invokeStaticInterfaceMethod(MethodDescriptor.of(method), realParamsHandle));
} else {
tryCatch.assign(invokeRet,
tryCatch.invokeStaticMethod(MethodDescriptor.of(method), paramsHandle));
tryCatch.invokeStaticMethod(MethodDescriptor.of(method), realParamsHandle));
}
} else {
if (Modifier.isInterface(clazz.flags())) {
tryCatch.assign(invokeRet,
tryCatch.invokeInterfaceMethod(MethodDescriptor.of(method), whenBase, paramsHandle));
tryCatch.invokeInterfaceMethod(MethodDescriptor.of(method), whenBase, realParamsHandle));
} else {
tryCatch.assign(invokeRet,
tryCatch.invokeVirtualMethod(MethodDescriptor.of(method), whenBase, paramsHandle));
tryCatch.invokeVirtualMethod(MethodDescriptor.of(method), whenBase, realParamsHandle));
}
}

Expand Down

0 comments on commit ed1f03a

Please sign in to comment.