I’ve thought about my problem from the last post a bit, and I have decided that the current situation actually isn’t so bad. I went with an approach that’s similar to the 2nd option that I have described, but a bit more permissive.
The class containing a predicate method should be public if it is a top-level class, and public static if it is a nested class. If it is a nested class, then all of its enclosing classes must also fulfill these criteria. This makes a method accessible from any static context, anywhere. However, when a violation is detected, I only issue a detailed warning. I opted for a warning instead of aborting the instrumentation process because in many cases, the programs still work for some reason if the instrumentation is done offline. Only in on-the-fly instrumentation are these warnings important.
I have now implemented the code for issuing these warnings and have also created a simpler
TCRun class that makes it very easy for the user to run programs with on-the-fly Thread Checker instrumentation.
Now I should do some more tests with
@Combine-style annotations, and then I need to package the Thread Checker conveniently, write documentation and release it. Yay!
Another thing I should do is check if classes have already been auto-generated during previous on-the-fly runs. The auto-generation for
@Combine-style annotations can take a while, so it would be highly desirable to reuse already existing classes.