Skip to content

Commit

Permalink
Use proper return type when indexing suspend functions
Browse files Browse the repository at this point in the history
This was not a problem with Jackson or Jsonb, because they
used the object class to determine the type of serializer,
but it is needed for Kotlin serialization which actually
used the generic type provided in the MessageBodyWriter
params to determine the serializer

Addresses: ##9003 (comment)
  • Loading branch information
geoand committed Jan 20, 2022
1 parent 8f095bf commit c273a64
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -553,9 +553,10 @@ private ResourceMethod createResourceMethod(ClassInfo currentClassInfo, ClassInf
}
}

Type nonAsyncReturnType = getNonAsyncReturnType(methodContext.containsKey(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)
Type methodContextReturnTypeOrReturnType = methodContext.containsKey(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)
? (Type) methodContext.get(METHOD_CONTEXT_CUSTOM_RETURN_TYPE_KEY)
: currentMethodInfo.returnType());
: currentMethodInfo.returnType();
Type nonAsyncReturnType = getNonAsyncReturnType(methodContextReturnTypeOrReturnType);
addWriterForType(additionalWriters, nonAsyncReturnType);

String[] produces = extractProducesConsumesValues(getAnnotationStore().getAnnotation(currentMethodInfo, PRODUCES),
Expand Down Expand Up @@ -622,7 +623,8 @@ private ResourceMethod createResourceMethod(ClassInfo currentClassInfo, ClassInf
toClassName(currentMethodInfo.returnType(), currentClassInfo, actualEndpointInfo, index))
// FIXME: resolved arguments ?
.setReturnType(
determineReturnType(currentMethodInfo, typeArgMapper, currentClassInfo, actualEndpointInfo, index));
determineReturnType(methodContextReturnTypeOrReturnType, typeArgMapper, currentClassInfo,
actualEndpointInfo, index));

if (httpMethod == null) {
handleClientSubResource(method, currentMethodInfo, index);
Expand Down Expand Up @@ -686,13 +688,12 @@ protected boolean doesMethodHaveBlockingSignature(MethodInfo info) {
return true;
}

private String determineReturnType(MethodInfo info, TypeArgMapper typeArgMapper, ClassInfo currentClassInfo,
private String determineReturnType(Type returnType, TypeArgMapper typeArgMapper, ClassInfo currentClassInfo,
ClassInfo actualEndpointInfo, IndexView index) {
Type type = info.returnType();
if (type.kind() == Type.Kind.TYPE_VARIABLE) {
type = resolveTypeVariable(type.asTypeVariable(), currentClassInfo, actualEndpointInfo, index);
if (returnType.kind() == Type.Kind.TYPE_VARIABLE) {
returnType = resolveTypeVariable(returnType.asTypeVariable(), currentClassInfo, actualEndpointInfo, index);
}
return AsmUtil.getSignature(type, typeArgMapper);
return AsmUtil.getSignature(returnType, typeArgMapper);
}

protected abstract boolean handleBeanParam(ClassInfo actualEndpointInfo, Type paramType, MethodParameter[] methodParameters,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,18 @@ class GreetingResource {
return Person("Jim Halpert")
}

@Path("suspend")
@GET
@Produces(MediaType.APPLICATION_JSON)
suspend fun suspendHello(): Person {
return Person("Jim Halpert")
}

@Path("suspendList")
@GET
@Produces(MediaType.APPLICATION_JSON)
suspend fun suspendHelloList() = listOf(Person("Jim Halpert"))

@POST
@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,39 @@ open class ResourceTest {
))
}

@Test
fun testSuspendGet() {
given()
.`when`().get("/suspend")
.then()
.statusCode(200)
.body(`is`(
"""
{
"name": "Jim Halpert",
"defaulted": "hi there!"
}""".trimIndent()
))
}

@Test
fun testSuspendGetList() {
given()
.`when`().get("/suspendList")
.then()
.statusCode(200)
.body(`is`(
"""
[
{
"name": "Jim Halpert",
"defaulted": "hi there!"
}
]
""".trimIndent()
))
}

@Test
fun testPost() {
given()
Expand Down

0 comments on commit c273a64

Please sign in to comment.