Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Qute generated value resolvers - fix varArgs methods with 1 argument #31477

Merged
merged 1 commit into from
Feb 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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