Can’t wrap my head around this IR problem, can any...
# compiler
n
Can’t wrap my head around this IR problem, can anyone help? The simplified goal is: • Users can annotate some declarations with
@ImportantForInitialization
. • I provide a function called
initialize()
. Its body, IR-generated, should use info from all declarations above. If we provide
initialize()
via a companion runtime library, there’s no way for my plugin to modify its IR. If we have the user provide an empty
@Initializer fun initialize() = Unit
it works. But I struggle to make this work in multimodule or even multiplatform setups. • multimodule: there’ll be a graph of initialize functions, ideally they should be calling each other. It may be possible because there’s
IrModuleFragment.descriptor.allDependencyModules
. But
descriptor.stableName
is nullable for dependencies - I think - so it’s hard to provide/retrieve a stable FQN for the initialize function. • multiplatform: no problem in K1, but I read that in K2 common sources are compiled on their own, so basically I’d have to require an initializer in common (collecting
@ImportantForInitialization
in that unit) and another for each platform. It sucks. I also know I can write metadata in annotations but I still need the FQN of something in order to read any annotation on it.
t
Correct me if I'm wrong, but you would like to automatically find all initialize functions in all modules for all platforms? That's a bit expensive.
Technically you can get everything annotated in one module with predicates in a FIR plugin: https://github.com/JetBrains/kotlin/blob/master/docs/fir
j
It is not very safe you need to call a function that you need to modify from a module that you don’t own or you don’t apply your compiler plugin. This would only be safe in an isolated project and by throwing errors in build phase in each module that does not add your compiler plugin.
n
Yes, it would be processed and validated by my plugin in all modules. The problem is just how to find it and whether that strategy (whatever it is) works with K2 multiplatform compilation scheme too
t
What about adding a meta-info file like java auto service into the modules that contains this initialization mechanism and put all the FQN into that file. This file could be made by your plugin and then at a later stage read by your plugin to get the FQN-s. You could get all these files with Gradle from the classpath.
n
That is a good idea. But my target is KN and I think we can’t bundle anything in klibs ( https://youtrack.jetbrains.com/issue/KT-54850/Provide-mechanism-for-compiler-plugins-to-add-custom-information-into-binaries ). I’d need a separate artifact with some special classifier, injected into maven publications, care about project() dependencies. It seems a bit too complex
t
Yes, fully automatic solution is complex. I typically resort to some kind of manual registration during application bootstrap. That's easy to implement.