inline fun <reified Type> createAPI(baseUrl: String, okHttpClient: OkHttpClient): Type =
Class.forName(Type::class.qualifiedName + "Impl")
.constructors.first().newInstance(baseUrl, okHttpClient) as Type
KRequest is now using the create function based on the reflection API, which will lead to unnecessary overhead. Consider replacing it with the generated corresponding implementation class directly using the Kotlin compiler plugin.
KRequest has the following convention for generated classes: '{{Your Api Interface name}}Impl'. So it can be implemented in the following way.
object KRequest {
fun <T> create(baseUrl: String, okHttpClient: OkHttpClient): T {
throw NotImplementedError("This implementation will be substituted by the compiler plugin")
}
}
This is a KRequest object that includes a create function. The function accepts two parameters, baseUrl and OkHttpClient. The call to this function will be overridden by the Kotlin compiler plugin to directly call the corresponding implementation class's constructor.
class KRequestIrGenerator : IrGenerationExtension {
override fun generate(moduleFragment: IrModuleFragment, pluginContext: IrPluginContext) {
moduleFragment.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitCall(expression: IrCall): IrExpression {
if (expression.symbol.owner.name.asString() == "create" &&
expression.dispatchReceiver?.type?.classFqName?.asString() == "KRequest"
) {
val apiType = expression.typeArguments[0]?.classFqName!!
val apiImplName = "${apiType.asString()}Impl"
val apiClassImplSymbol =
pluginContext.referenceClass(ClassId(FqName.ROOT, Name.identifier(apiImplName)))
val constructorSymbol = apiClassImplSymbol?.constructors?.toList()
?.get(0)!!
val constructorCall = IrConstructorCallImpl.fromSymbolOwner(
expression.startOffset, expression.endOffset,
constructorSymbol.owner.returnType,
constructorSymbol
)
constructorCall.putValueArgument(0, expression.getValueArgument(0))
constructorCall.putValueArgument(1, expression.getValueArgument(1))
return constructorCall
}
return super.visitCall(expression)
}
})
}
}
The above IR Transformer will inspect the create method calls on KRequest objects. Whenever a match is found, it will replace this call with a direct constructor call to eliminate the overhead incurred by the previous use of reflection.
KRequest is now using the create function based on the reflection API, which will lead to unnecessary overhead. Consider replacing it with the generated corresponding implementation class directly using the Kotlin compiler plugin. KRequest has the following convention for generated classes: '{{Your Api Interface name}}Impl'. So it can be implemented in the following way.
This is a KRequest object that includes a create function. The function accepts two parameters, baseUrl and OkHttpClient. The call to this function will be overridden by the Kotlin compiler plugin to directly call the corresponding implementation class's constructor.
The above IR Transformer will inspect the create method calls on KRequest objects. Whenever a match is found, it will replace this call with a direct constructor call to eliminate the overhead incurred by the previous use of reflection.