Skip to content

Commit ce62d50

Browse files
authored
Merge pull request #31477 from mkouba/issue-31449
Qute generated value resolvers - fix varArgs methods with 1 argument
2 parents 269da7b + ed1f03a commit ce62d50

File tree

2 files changed

+58
-5
lines changed

2 files changed

+58
-5
lines changed

extensions/qute/deployment/src/test/java/io/quarkus/qute/deployment/varargs/VarargsMethodTest.java

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,11 @@
22

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

5+
import java.util.Arrays;
6+
57
import jakarta.inject.Inject;
8+
import jakarta.inject.Named;
9+
import jakarta.inject.Singleton;
610

711
import org.jboss.shrinkwrap.api.asset.StringAsset;
812
import org.junit.jupiter.api.Test;
@@ -22,23 +26,38 @@ public class VarargsMethodTest {
2226
.addAsResource(new StringAsset("{foo.getStr}:{foo.getStr('foo','bar','baz')}"),
2327
"templates/foo.txt")
2428
.addAsResource(new StringAsset("{fmt.format('a','b','c')}"),
25-
"templates/bar.txt"));
29+
"templates/bar.txt")
30+
.addAsResource(new StringAsset("{foo.getInt}:{foo.getInt(1)}:{foo.getInt(1,2,3)}"),
31+
"templates/baz.txt")
32+
.addAsResource(
33+
new StringAsset(
34+
"{cdi:qux.getBoolean(1)}:{cdi:qux.getBoolean(1, true, false)}:{cdi:qux.getBoolean(2, false)}"),
35+
"templates/qux.txt"));;
2636

2737
@Inject
2838
Template foo;
2939

3040
@Inject
3141
Template bar;
3242

43+
@Inject
44+
Template baz;
45+
46+
@Inject
47+
Template qux;
48+
3349
@Test
3450
public void testVarargs() {
3551
assertEquals("ok:foo:bar baz", foo.data("foo", new Foo()).render());
3652
assertEquals(" b a", bar.data("fmt", "%2$2s%1$2s").render());
53+
assertEquals("[]:[1]:[1, 2, 3]", baz.data("foo", new Foo()).render());
54+
assertEquals("1 []:1 [true, false]:2 [false]", qux.render());
3755
}
3856

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

60+
// This one is ignored
4261
String getStr(String foo) {
4362
return foo;
4463
}
@@ -52,11 +71,25 @@ public String getStr(String foo, String... args) {
5271
return foo + String.format(":%s %s", args[0], args[1]);
5372
}
5473

74+
public String getInt(int... args) {
75+
return Arrays.toString(args);
76+
}
77+
5578
@TemplateExtension
5679
static String format(String fmt, Object... args) {
5780
return String.format(fmt, args);
5881
}
5982

6083
}
6184

85+
@Named
86+
@Singleton
87+
public static class Qux {
88+
89+
public String getBoolean(int first, Boolean... args) {
90+
return first + " " + Arrays.toString(args);
91+
}
92+
93+
}
94+
6295
}

independent-projects/qute/generator/src/main/java/io/quarkus/qute/generator/ValueResolverGenerator.java

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -690,21 +690,41 @@ private void matchMethod(MethodInfo method, ClassInfo clazz, MethodCreator resol
690690
exception.invokeVirtualMethod(Descriptors.COMPLETABLE_FUTURE_COMPLETE_EXCEPTIONALLY, whenRet,
691691
exception.getCaughtException());
692692

693+
ResultHandle[] realParamsHandle = paramsHandle;
694+
if (isVarArgs(method)) {
695+
// For varargs the number of results may be higher than the number of method params
696+
// First get the regular params
697+
realParamsHandle = new ResultHandle[parameterTypes.size()];
698+
for (int i = 0; i < parameterTypes.size() - 1; i++) {
699+
ResultHandle resultHandle = tryCatch.invokeVirtualMethod(Descriptors.EVALUATED_PARAMS_GET_RESULT,
700+
whenEvaluatedParams, tryCatch.load(i));
701+
realParamsHandle[i] = resultHandle;
702+
}
703+
// Then we need to create an array for the last argument
704+
Type varargsParam = parameterTypes.get(parameterTypes.size() - 1);
705+
ResultHandle componentType = tryCatch
706+
.loadClass(varargsParam.asArrayType().component().name().toString());
707+
ResultHandle varargsResults = tryCatch.invokeVirtualMethod(Descriptors.EVALUATED_PARAMS_GET_VARARGS_RESULTS,
708+
evaluatedParams, tryCatch.load(parameterTypes.size()), componentType);
709+
// E.g. String, String, String -> String, String[]
710+
realParamsHandle[parameterTypes.size() - 1] = varargsResults;
711+
}
712+
693713
if (Modifier.isStatic(method.flags())) {
694714
if (Modifier.isInterface(clazz.flags())) {
695715
tryCatch.assign(invokeRet,
696-
tryCatch.invokeStaticInterfaceMethod(MethodDescriptor.of(method), paramsHandle));
716+
tryCatch.invokeStaticInterfaceMethod(MethodDescriptor.of(method), realParamsHandle));
697717
} else {
698718
tryCatch.assign(invokeRet,
699-
tryCatch.invokeStaticMethod(MethodDescriptor.of(method), paramsHandle));
719+
tryCatch.invokeStaticMethod(MethodDescriptor.of(method), realParamsHandle));
700720
}
701721
} else {
702722
if (Modifier.isInterface(clazz.flags())) {
703723
tryCatch.assign(invokeRet,
704-
tryCatch.invokeInterfaceMethod(MethodDescriptor.of(method), whenBase, paramsHandle));
724+
tryCatch.invokeInterfaceMethod(MethodDescriptor.of(method), whenBase, realParamsHandle));
705725
} else {
706726
tryCatch.assign(invokeRet,
707-
tryCatch.invokeVirtualMethod(MethodDescriptor.of(method), whenBase, paramsHandle));
727+
tryCatch.invokeVirtualMethod(MethodDescriptor.of(method), whenBase, realParamsHandle));
708728
}
709729
}
710730

0 commit comments

Comments
 (0)