Unsolved Problems

There are still a few unsolved problems, most of them concerning arrays of annotations, or arrays in general. Some concern arrays that have a different size than the default value, some concern arrays with zero elements, for which it is more difficult to get the element type. Mostly, I have pondered how to deal with arrays of annotations, though, but I haven’t actually implemented anything yet. I have considered passing the members of annotation array elements as individual arrays, but that creates problems too:

@PredicateLink(MyPredicates.class)
@interface MyAnnotation {
String value;
int i;
}

@Combine
@interface MyCombined {
MyAnnotation[] value();

}
// auto-generated predicate for MyCombined:
// boolean check(Object thisO, String[] value, int[] i);

In this example, instead of passing an array of MyAnnotation, I could pass two arrays, one array of String and one array of int. That has the advantage that I don’t have to use RUNTIME retention or create my own runtime representation for the data in MyAnnotation. This gets problematic, though, when the array elements contain arrays themselves, i.e. when there’s an array in MyAnnotation:

@PredicateLink(MyPredicates.class)
@interface MyAnnotation {
String[] value;
int i;
}

@Combine
@interface MyCombined {
MyAnnotation[] value();

}
// auto-generated predicate for MyCombined:
// boolean check(Object thisO, String[][] value$value, int[] value$i);

This isn’t too bad yet, except that such an array of arrays is becoming rather painful to create. The $ is just there to help distinguish members from different fields. It gets worse, though, when the array is an array of annotations:

@PredicateLink(MyPredicates.class)
@interface MyAnnotation {
String[] value;
int i;
}

@Combine
@interface MyCombined {
MyAnnotation[] value();
MyAnnotation other();
}

@Combine
@interface MyCombinedCombined {
MyCombined[] value();
MyAnnotation other();
}
// auto-generated predicate for MyCombined:
// boolean check(Object thisO,
// String[][][] value$value$value, int[][] value$value$i,
// String[][] value$other$value, int[] value$other$i,
// String[] other$value, int other$i);

Do I really want to do this? Here it also becomes more apparent why the $ is needed, but that’s not the problem, I handle that already. I don’t think separating arrays this way is such a good idea. Another thing I could do would be to automatically generate a storage data structure for an annotation used in an array, something like a struct in C++, i.e. for MyAnnotation I would generate a MyAnnotationStruct that just has two public fields, String[] value and int i. Then I could more easily pass the data as array, the way it was intended.

At this point, however, I’m starting to wonder if maybe I should just use RUNTIME retention instead. I should really write a version that uses RUNTIME retention and reflection to do everything. It may solve some problems more elegantly, like this one, and at least serve as a way to compare performance.

I think my first cut will be the “code bloat” approach, though: I will generate a new predicate for each new array size. To accommodate for multiple arrays in several places, I can simply enumerate the arrays along a preorder walk and include index-size pairs in the predicate method name: check$1-2$2-0$3-0 would be the appropriate predicate for an annotation whose first array has two elements and whose second and third array have zero elements.

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. Bookmark the permalink.

Leave a Reply