hi! I’m trying to develop a plug-in with the new F...
# compiler
a
hi! I’m trying to develop a plug-in with the new FIR infrastructure, and I have a couple of questions: • in order for the plug-in to work, we need to scrape information from all functions in the CLASSPATH with a certain attribute: is the
FirTypeAttributeExtension
ensured to be run over all possible functions before the next steps in the analysis continue; if not, what is the best way to perform this? • the analysis works in two stages; what is the best way for a FIR plug-in to introduce several stages? thanks very much in advance!
d
Hi
we need to scrape information from all functions in the CLASSPATH with a certain attribute
In FIR plugins which generate some declarations we don't provide a way to lookup whole classpath, because cost of such operation is too high (which blocks using of such plugin in IDE). All you can do is: 1. Get symbol for declarations with specific `classId`/`callableId` 2. Get all declarations from source code which are matching some annotation based predicate (e.g. "all classes annotated with
@foo.Ann
) And what do you mean by "attribute of function"?
what is the best way for a FIR plug-in to introduce several stages?
I didn't get it, can you please elaborate your question?
Also note that FIR plugin API which is now in kotlin master is a prototype and not ready even for preview (as FIR itself), which means that: 1. Not all extensions which we want to provide are implemented yet (e.g. there is no extension for providing custom contracts) 2. API of existing extensions can be changed dramatically (but main principles of them will stay) 3. There is no way to run compiler with FIR plugin besides declaring compiler test I will publish some post with explanations of how plugin API works when it will be more or less stable and complete
a
thanks for your help! elaborating a bit more: • with “attribute of function” I meant something like elements matching some annotation based predicate, but over the classpath, instead of only the source code (I know it’s expensive, but I see no other way of getting this information) • with “stages” I mean have a series of steps in your analysis, let’s say, two checks in which the second depends on information gathered on the first; as I see right now there are no guarantees on this respect
d
I see no other way of getting this information
What is your usecase for this? And
FirTypeAttributeExtension
is used for extending type system, not for collecting any info for declarations
with “stages” I mean have a series of steps in your analysis
Plugins are integrated with predefined frontend phases and can not introduce additional ones, because in IDE there are no guaranties that whole world will be resolved to specific phase before running next one (moreover it's almost never true) Can you also provide usecase for this too?
a
sure! we are investigating how to port our static analysis plug-in [https://github.com/arrow-kt/arrow-meta/tree/main/plugins/analysis/kotlin-plugin] to the new FIR framework. Right now it works as follows: 1. the plug-in harvests some annotations from the CLASSPATH, which describe the pre and postconditions of a function -> this is when gathering the whole thing is important, as usually you’ll use functions from a third-party library (in fact, we allow having pre/postconditions separate from the functions themselves, but that’s another thing) 2. we also harvest pre/postconditions from things like
require
blocks 3. then we go into the bodies of the declarations and ensure that the preconditions for all method calls are satisfied right now we stage (2) and (3) by performing (2), and then using a
Retry
in the compiler; a mutable variable with the current stage points towards which is the thing to be done in each case
d
You can implement such analyzer in a reversed way: you create function call checker in plugin, which will be called on each function call. In this checker you see to which function this call was resolved, check it's annotations for preconditions and then ensure that they are satisfied I don't understand, why you need to perform steps 1 and 2 beforehead.
Am I right that if I create project with one hello wrold file but with a lot of dependencies with functions with preconditions then time of analysis with your plugin will increase lineary with size of classpath?
a
Well, we try to be a bit clever on loading them, but in our current approach that would happen (but only linearly on the size of packages with functions with preconditions)
Our problem is the following: we want to be able to add preconditions to functions outside our control (like the standard library). We do so by creating a fake function with the precondition and an annotation which includes the fully qualified name of the actual function this precondition applies to
Those are the ones which are hard to harvest, because they do not appear as annotations of the actual function we are calling
Having said so, I'm happy to go for another way to handling this, we just went towards the least resistance path in our current implementation