Problem:
I have to methods: showFoo()
and doHeavy()
.
The former should always be called on EDT and the latter should never be called there.
I want to have static analysis for that.
Possible solution:
Imagine the following annotations
@ThreadAttribute(Threads.EDT)
fun showFoo(){}
@ThreadAttribute(Threads.NON_EDT)
fun doHeavy(){
showFoo(); //Compilation error, wrong attributes
}
// No attribute, could be called from anywhere
fun runOnEdt() {
@SetAttributeExplicitly(ThreadAttribute=Threads.EDT) // I swear to run it on EDT, trust me
SwingUItils.invokeAndWait { showFoo() }
}
Here: ThreadAttribute
is just a custom annotation. One may create Heavy
and Light
annotations to prevent calling “heavy” functions from “light” functions (Have you seen those comments in interfaces like “this function is called many times per second, do not do anything heavy here”?)
Anon
and Authotizated
annotations so people can’t call functions that require authorization from “anon”, Remote
annotation (for proxy classes for SOAP/REST/RPC) so one can’t run remote call on EDT etc.
Language should do 2 things:
- Check that when
foo()
callsbar()
and both of them have attributes, they match. - Provide
SetAttributeExplicitly
to change attribute explicitly.
My idea is raw. For example, I am not sure if we can inference attributes transitively:
// Can we assume that we have ThreadAttribute(Threads.EDT) here?
// What if showBar() has different attribute?
fun showFooAndBar() {showFoo(); showBar()}
The other problem is that this idea only works when you have most of your code annotated. So, there should be ability to disable this functionality for module.
However, I still believe it will make a great aid when dealing with multithread code or code with “heavy” and “light” functions.