I am running into some issues regarding generics, recursion and inline reified.
First, I want to recursively call a method that uses generics. This method makes request calls from a stack of requests. Lets say 5 requests need to be made, where 4 are done under the hood and only the last one is important. The others are sanity checks.
private fun <T : EmptyStateInfo> multipleRequests(
callback: Callback<T>?
) {
...
// request is made here. On the success of that request, this method is called again to make another request. I use a linkedList of requests to keep track.
}
Now that the sanity check requests are made and successful, the last request I would like to bubble up the response (or error) to the presentation layer. The problem I am facing is that the method for processing the response is inline reified. I am unable to call this method without receiving the error, "cannot use T as a reified type parameter".
private inline fun <reified T : EmptyStateInfo> handleResponse(
response: Response,
callback: Callback<T>?
) = when (response) {
is Response.StringResponseItem -> {
try {
val responseData = gson.fromJson(response.data, T::class.java)
...
// do something with response data
} catch (e: JsonSyntaxException) {
handleNonHttpFailure(e, callback)
}
}
}
How to solve this issue? Here is what I have tried.
inline function 'private final inline fun multipleRequests()' cannot be recursive
Anyone with any ideas on how to approach this problem?
You don't really need reified T
in your handleResponse
method, neither you want to inline it as you're generating ton of trash bytecode.
What you can do is have inlined method overload which pulls class out of reified parameter and calls normal method which can be called recursively without issue:
// reified entry point
private inline fun <reified T : EmptyStateInfo> multipleRequests(callback: Callback<T>?) = multipleRequests(callback, T::class.java)
// recursive method
private fun <T : EmptyStateInfo> multipleRequests(callback: Callback<T>?, tClass : Class<T>) {
// ... calls requests passing tClass as argument
}
private fun <T : EmptyStateInfo> handleResponse(
response: Response,
callback: Callback<T>?,
tClass : Class<T>){
// ... something something
val responseData = gson.fromJson(response.data, tClass)
// ... etc
}