is it possible to write a frontend compiler plugin...
# compiler
e
is it possible to write a frontend compiler plugin to manipulating the AST?
y
Officially, no. There are endpoints for specific things (Assign alterer is one of the coolest, since it allows you to add arbitrary FIR at this position, and it gets resolved after). By AST I'm assuming you mean FIR. If you want to manipulate the actual AST, you could probably write a pre-processor or something that uses the compiler to parse code into AST, modifies it, and turns it back into kotlin source files, then passes those on to the compiler. You'd have no IDE support though. For FIR, there are some unofficial tricks though. For instance, status transformer gives you access to a declaration. As a result, you can just edit the declaration's body right there. The body won't be resolved, obviously. You can combine some of these extensions, though. For instance, status transformer can insert dummy
someSpecialNameHere = someCode
assignments at arbitrary points in a declaration's body, and then assign alterer can come in and replace those assignments with arbitrary FIR (and with the initial part of the body now resolved).
FirFunctionCallRefinementExtension
can also be (ab)used to let you edit the arguments to function calls, and it can be especially helpful to add assignments inside lambdas so that you can add arbitrary FIR. I have some examples here and here. Do note that they're hacky though, and thus there's no guarantee they'll continue working.
c
In the same vein: is there any way to add custom keywords or constructs through the plugin API? It seems like you're saying "no", but I want to double-check. Also, are you saying that the AssignmentPlugin hook is the only way to get it to generate arbitrary FIR? There's really no way to just add your own visitors to the tree?
I wish the compiler plugin API were more fleshed-out. It's the only way to definitively prove that a proposed feature won't break the language.
👏 1
y
You can't add keywords, but annotations can do the job pretty well a lot of the time. Assignment plugin is (as far as I can tell) one of the only way to generate arbitrary FIR that then gets resolved. You can generate FIR in a bunch of places if you don't need it to be resolved. The other way to add arbitrary FIR is the status transformer (but that's not an official use case), which allows you to edit a function's body before it's resolved.
👍 1
c
> only way to generate arbitrary FIR that then gets resolved. You can generate FIR in a bunch of places if you don't need it to be resolved. What do you mean by that when you say "resolved"? What is the difference between FIR that's emitted before being resolved and after being resolved?
Or is that actually the problem I'm running into in https://kotlinlang.slack.com/archives/C7L3JB43G/p1762789130428969: that the AssignmentAltererExtension is run during an "everything is solely referred to by name" phase, before the symbols the names actually refer to can be looked up/"resolved"?
y
Assignment altered extension guarantees that its LHS is resolved, but makes no such guarantee about it's RHS (it's always unresolved, unless another plugin has done something weird to it like with status transformer). So yes, you can't check the type of the RHS. you can usually get by though by returning a call to a function overloaded on that RHS.
Type checking then is based on whether that function call you create is successful or not
👍 1