I'd like to better understand what FIR plugins are...
# compiler
p
I'd like to better understand what FIR plugins are. I understand they're related to IDE support and that FIR stands for Frontend IR (right?). But why aren't just backend IR plugins enough for the IDE? Do compiler plugins always come in pairs (backend and frontend), like socks? And finally, is FIR plugin needed if I plan to work only with backend IR? What would the plugin do in such case? CC @Big Chungus
đź‘€ 1
h
I really recommend you to watch this video:

https://www.youtube.com/watch?v=iTdJJq_LyoYâ–ľ

j
With backend plugins you don’t have any IDE support, for example if you want yo generate a new function like kotlin serialization does you are not going to see it exists without compiling. Similar behavior you get when you use dagger with kapt or ksp and you try to use any generated function before it exists. With FIR you don’t need to wait and in the same moment the user finishes to write the annotation (Serializable for example) you already can access to the generated function
p
Got it, thanks! I somehow thought just the backend IR plugin already provides it
So the frontend plugin triggers the backend plugin? Is it the correct mental model?
(I'll better watch the video first)
j
frontend runs before and backend later but I wouldn’t call front triggers backend
h
No, there is no plugin releationship between frontend plugins and backend plugins. Plugins operate on some code representation and you could use multiple frontend/backend plugins.
j
you can generate a function in FIR which has no body, later in backend you are going to be able to see it and add a body
at same time with FIR you can add checkers so you can report issues without compiling everything
and those reports are going to be shown in the IDE
as you are talking about DSL, probably the DslMarker annotation works in that way
h
You use different representations for different use cases, for example, the frontend code use case is analyzing and checking the types, etc. The backend use case is code generation, the representation is already checked and focuses on optimizing/lowering to the target code. IDE "only" needs frontend representation for helping you with code assistance.
b
Does IntelliJ support custom FIR already or is it still reserved for JB plugins only?
j
And here you can see prototypes and plugins that are in k2 • https://github.com/JetBrains/kotlin/tree/master/plugins I highly recommend to see the
fir-plugin-prototype
one, and its tests to understand what it is doing, for example this test • https://github.com/JetBrains/kotlin/blob/master/plugins/fir-plugin-prototype/testData/diagnostics/checkers/simple.kt As you can see in that file, there is a great test infrastructure to test diagnostics with a simple syntaxis
<!FUNCTION_WITH_DUMMY_NAME!>
@Big Chungus AFAIK the only way to use FIR is to compile IntelliJ IDEA itself with a flag enabled.
Anyway if you want to play with it, the test infrastructure is really amazing, we worked on some FIR codegen for weeks/months and when we compiled the IDE it was working as it worked on tests. The tests itself autogenerates the FIR and IR code in text files, so if it is wrong but you don't know how to write with precision the FIR and IR code (as the code is not familiar, but readable), you can just remove the txt files, change the plugin implementation and check if the new ones generated are correct.
d
If you want to create some private declarations or modify bodies of user-defined functions than it can be done only at IR level If you want to make some user-visible changes (generate new functions which can be called by user, add new supertypes, extend type system, etc) then you need to create frontend (FIR) plugin for it, because call resolution and other static analysis stuff is performed on frontend (and it's better to create bodies of generated declarations in IR) Also if you want to make changes from your plugin visible in IDE then you need to use frontend, because IDE does not run backend at all (except Show Kotlin Bytecode action)