Jesper Åman
05/22/2022, 10:48 AMIrGenerationExtension
that generates some classes and methods, in some of the method bodies I need to include a super call, however, it's not entirely clear to me how to achieve this through the IR-apis. With this code, which is meant to just call super.onCreate()
in a subclass of `android.app.Application`:
override fun visitFunctionNew(declaration: IrFunction): IrStatement {
if (declaration.name.asString() == "onCreate"
&& declaration.parentAsClass.hasAnnotation(pluginContext.externalConfigApplicationAnnotation)
) {
...
// If body does not already exist
declaration.body = pluginContext.irBlockBody(declaration.symbol) {
+irCall(declaration, superQualifierSymbol = pluginContext.applicationClass).apply {
dispatchReceiver = irGet(declaration.dispatchReceiverParameter!!)
}
...
}
...
}
return super.onVisitFunctionNew(declaration)
}
I'm getting the following error:
Caused by: java.lang.AssertionError: SyntheticAccessorLowering should not attempt to modify other files!
While lowering this file: FILE fqName:c.z.a.e.sample fileName:/.../MainActivity.kt
Trying to add this accessor: FUN SYNTHETIC_ACCESSOR name:access$onCreate$s-1072845520 visibility:public modality:FINAL <> ($this:android.app.Application) returnType:kotlin.Unit
Seems like rather than just invoking super, it tries to generate a synthetic accessor. Any ideas as to why this is not working?
I do have a workaround currently that involves just injecting the java byte code further down the chain via a ClassBuilderInterceptorExtension
, but would very much like to avoid this if possible.
I'm seeing that there are ways to achieve this easily when dealing with constructors, e.g. +irDelegatingConstructorCall(...)
, is there something similar available for functions generally?lhwdev
05/22/2022, 4:41 PM+irCall(declaration, ...)
, not MyClass.onCreate but SuperClass.onCreate?Jesper Åman
05/22/2022, 7:51 PMval superSymbol = pluginContext.applicationClass.getSimpleFunction("onCreate")!!
declaration.body = pluginContext.irBlockBody(superSymbol) {
+irCall(declaration, superQualifierSymbol = pluginContext.applicationClass).apply {
dispatchReceiver = irGet(declaration.dispatchReceiverParameter!!)
}
...
}
Tried some variations as well, such as providing superSymbol.owner
instead of declaration
to irCall
lhwdev
05/23/2022, 12:32 PMIrBuilderWithScope.irBlockBody()
?
I meant passing superSymbol
to +irCall(declaration <- here).lhwdev
05/23/2022, 12:34 PMIrElement.dump()
) from - bare kotlin code, and - what you generated, then compare them.