@Combine Almost Done

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:

  1. 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 have RUNTIME retention? Annotations look like interfaces. Do I make make method calls to retrieve the data?
  2. 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.

Share

About Mathias

Software development engineer. Principal developer of DrJava. Recent Ph.D. graduate from the Department of Computer Science at Rice University.
This entry was posted in Concurrent Unit Testing, DrJava. Bookmark the permalink.

Leave a Reply