It has taken me longer than expected, but I just felt exhausted after I finished the implementation of @PredicateLink
-type annotations, and I had to slow down a little. I also struggled with fixing DrJava bug [ 1578865 ], and that consumed about two afternoons, without a successful end thus far.
Now I have almost finished the implementation of @Combine
, and I can (almost) do cool things like these:
@Combine
@interface OrNames {
OnlyThreadWithName[] value();
}
@Combine(Combine.Mode.AND)
@interface NameAndGroup {
OnlyThreadWithName name()
default @OnlyThreadWithName("foo");
OnlyThreadWithGroupName group()
default @OnlyThreadWithGroupName("main");
}
@Combine(Combine.Mode.OR)
@interface CombineCombine {
OrNames names()
default @OrNames({
@OnlyThreadWithName("foo"),
@OnlyThreadWithName("bar")});
NameAndGroup nameAndGroup()
default @NameAndGroup();
}
@Combine(Combine.Mode.NOT)
public @interface NotEventThread {
OnlyEventThread value() default @OnlyEventThread;
}
What doesn’t work right yet is the handling of arrays of annotations, as in the @OrNames
annotation above. Right now, I produce one class file for each @Combine
-type annotation, and that class file includes exactly one method with all the parameters for all the member annotations.
The predicate method for @NameAndGroup
, for example, is boolean check(Object thisO, String a, boolean b, String c, boolean d)
, since all predicates have the value of this
or null
as first parameter, and the predicates of the two member annotations @OnlyThreadWithName
and OnlyThreadWithGroupName
both require a String
and a boolean
in addition to the Object thisO
.
Unfortunately, this approach of creating one method that has all the parameters required for its member annotations doesn’t work for arrays of annotations, of course, since the array can have a different number of elements every time the @Combine
-type annotation is used. I still like the general approach of flattening out the parameter list; it makes it very easy to pass the arguments to the member predicate methods. Now I have to figure out how I handle arrays of annotations.
There are two options that I see right now:
- Treat the array of annotations as one parameter, and then write some kind of
for
loop in the auto-generated predicate method to call the predicate method of every array element. The problem with this approach is that I don’t know how to treat an annotation as a value and access its parts at runtime. Would the annotation have to haveRUNTIME
retention? Annotations look like interfaces. Do I make make method calls to retrieve the data? - I create a new predicate method each time the number of elements differs. This is probably easier to do, but creates code bloat.
I may try to take a nap before I have to go to the office now, but considering that it’s 10 AM already, it’s pretty much pointless. I also have to figure out why the grading script didn’t work for Felipe on Friday.
Update: I guess there’s also the option of always using RUNTIME
retention and doing the entire lookup using reflection. Maybe I should do that as a comparison, but I have the feeling that this will be incredibly heavy-weight.