https://kotlinlang.org logo
#compiler
Title
# compiler
j

Jesper Åman

05/22/2022, 10:48 AM
Hi there, I'm writing a compiler plugin and am stuck on a (seemingly simple) problem. I have an
IrGenerationExtension
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`:
Copy code
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:
Copy code
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?
l

lhwdev

05/22/2022, 4:41 PM
Maybe you should provide the symbol of method of super class into
+irCall(declaration, ...)
, not MyClass.onCreate but SuperClass.onCreate?
j

Jesper Åman

05/22/2022, 7:51 PM
Thanks, tried, but getting the same error
Copy code
val 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
l

lhwdev

05/23/2022, 12:32 PM
I cannot figure out exact details, like providing symbol to
IrBuilderWithScope.irBlockBody()
? I meant passing
superSymbol
to +irCall(declaration <- here).
Maybe you can dump ir tree(
IrElement.dump()
) from - bare kotlin code, and - what you generated, then compare them.
5 Views