[type-annos-observers] Thoughts on names and scoping, arrays, annotation targets

Timo Kinnunen timo.kinnunen at gmail.com
Sat Aug 31 06:28:10 PDT 2013


Hi, 




I’ve been following Checker Framework for a while, then recently started working on debugging a type-checking plugin for it, and so now that I feel like I’ve gotten some handle on all this type annotation business, here’s feedback and impressions. 


Overall my impression is that the type annotations are the important driving force pushing things forward but the spec itself is only a necessary evil, a requirement to be fulfilled. That’s not a really exciting situation, but this could be improved with changes in the scoping, nested arrays and annotation targeting areas, I think.



The changes to how scoping is expressed in code is the one thing I really don’t like. The relationship between fully qualified names and imported simple names, nested classes and their enclosing classes, the pseudo-sub-package structure. These form a simple, straightforward, clean system. And now type annotations come straight into the middle of all of it. The result looks really ugly and changes which parts of code are emphasized:




void innerMethod(@Any Outer. at Backer Middle. at Counted Inner this, @Any Outer. at Backer Middle. at Nullable @Counted Inner other) { ... } 

// Quite apropos that those are mistaken for email addresses…



All those @Any and @Backer annotations deemphasize that one @Nullable. As well, the .@ syntax looks like a new dereferencing operator and makes it look like the type annotation is linked to the preceding type, not the type that follows!


These problems seem like collateral damage partly from nested-array annotations and partly from declaration/type-use annotation ambiguity, so nothing much can be done here.



Annotating multi-level arrays has way too much influence on the whole design for how rarely it gets used. The added complexity from annotations for each level on top of the complexity already present in nested arrays doesn’t help matters.




I read in the JSR308 design a section which said this: 


“The prefix notation is natural, because the type is read in exactly the same order as any Java array type. As another example, to express “non-null array of length-10 arrays of English Strings” a programmer would write”


And so I decided to try that as a test, without peeking at the answer.


The results are too long for this email, but essentially I ended up with the following three declarations:



// To express “non-null array of thing (length-10 arrays of English Strings)” write

public final @NonNull T[] array;
​// To express “length-10 array of thing (English Strings)” write 
public final @Length(10) T[] array;
​// To express “English String” write 
@Language("English") String s1 = "One";
​

To combine them I would much rather like to do the following. First, annotations should bind like this:



public final @NonNull T[] array; // This should…



public final @NonNull <T[]> array; // …mean this… 


public final <@NonNull T>[] array; // …rather than currently like this.
​

Then the rest is simple substitution:


public final @NonNull T[] array;

+

public final @Length(10) T[] array;

+

@Language("English") String s1;

=

public final @NonNull T[] array;

+

public final @Length(10) <@Language("English") String>[] array;

=

public final @NonNull <@Length(10) <@Language("English") String>[]>[] array;


Which is a non-null array of length-10 arrays of English language Strings when read in left-to-right, breadth-first order.



Last one is short and quick one on @Target meta-annotations. To allow the ambiguity between field declaration and type use annotations to be resolved without extra contortions, I’d like to be able to further constrain an annotation’s @Target at each site. So:



public final @Critical(@Target(FIELD)) String state;



The same should be possible to simulate in annotation processors already, but codifying it in the spec would be cleaner.


Also, @Target should allow the same targeting options as what the JVM supports. I don’t know why these are not revealed in the API, seems like a no-brainer.



Hopefully these can be helpful.











With regards, 
Timo Kinnunen


Sent from Windows Mail


More information about the type-annotations-spec-observers mailing list