[type-annos-observers] Constraining type annotations to occur just before type

Michael Ernst mernst at cs.washington.edu
Thu Mar 21 10:21:50 PDT 2013


Alex and Srikanth-

I agree entirely that it is terrible style to mix type annotations and
declaration annotations (the declaration annotations should always come
first) and that it is terrible style to mix type annotations with modifiers
(the modifiers should come first).  So, Alex's suggestion to change the
advice is definitely good.  Alex, can you make that change?  It's outside
the scope of the JSR 308 specification.

I consider it an infelicity in the Java grammar that (declaration)
annotations are considered modifiers and are lumped in with them, and even
worse that type annotations get lumped in with declaration annotations.
Logically, there are types and modifiers, and a type consists of optional
type annotations followed by a Java type.  This is how people should write
them.

Now, the question is whether or not the Java language should strictly
enforce this practice.

I'm sympathetic to this change -- probably my position is between
Srikanth's and Alex's.  I see the benefit of preventing confusing code
rather than just advising programmers not to write it in the first place
and then giving them rope to hang themselves.

But, here are a few downsides:
 * More grammatical ambiguity and more parsing complexity.
 * Any change so late in the game carries risks and extra work.  The work
   includes grammar changes and compiler changes.
 * Source code incompatibility with pre-Java-8 hacks that use
   declaration annotations to stand for type annotations.
Are there other downsides I am missing?


Incidentally, the Annotation File Utilities (AFU) grammar has these
productions:

decl-annotation ::=
    # annotation must be a declaration annotation.
    annotation

type-annotation ::=
    # annotation must be a type annotation.
    annotation

annotation ::=
    # The name may be the annotation’s simple name, unless the file
    # contains definitions for two annotations with the same simple name.
    # In this case, the fully-qualified name of the annotation name is required.
    "@"name [ "(" annotation-field [ "," annotation-field ]+ ")" ]

Elsewhere, the AFU grammar always uses the decl-annotation or
type-annotation non-terminal, rather than just using the "annotation"
non-terminal.  The AFU grammar would accept exactly the same annotation
files if it did not contain the decl-annotation and type-annotation
non-terminals, but those clarify the meaning.


We could imagine doing a similar thing with the JLS grammar, though the
required changes would be more extensive.  Modifiers would include
declaration annotations but not type annotations, which would be rolled
into types.  I suspect that the reason I didn't do this in the first place
was because I was trying to make the changes to the JLS grammar as minimal
as possible to clarify what was actually changing.  We've since moved away
from that position (and even if we hadn't, what's good for a diff isn't
necessarily good for a final version).

		    -Mike



> Subject: Re: Constraining type annotations to occur just before type
> From: Alex Buckley <alex.buckley at oracle.com>
> To: type-annotations-spec-experts at openjdk.java.net
> Date: Wed, 20 Mar 2013 11:53:32 -0700
>
> To be precise, the possibility of mixed TYPE_USE and non-TYPE_USE
> annotations occurs only where a production has been changed to use
> UnannType (or UnannReferenceType) because the production is preceded by a
> Modifier list (or VariableModifier list).
>
> Productions which continue to use Type (or ReferenceType) obviously allow
> only TYPE_USE annotations in the new [Annotations] non-terminal of Type.
>
> I agree that a TYPE_USE annotation is not a general modifier of a
> declaration. Semantically, it belongs with the type. The question is,
> should placing it among the declaration modifiers be considered a semantic
> error? I think the answer is no, because nothing bad happens at run time if
> you order modifiers unconventionally:
>
>   final @NonNull static private String s;
>
> A bigger problem as I see it is the longstanding JLS advice to write
> annotations as the first modifiers, before 'public', 'static', etc. This
> advice is definitely out of step with type annotations, because placing a
> TYPE_USE annotation at the front is obtuse:
>
>   @NonNull private static final String s;
>
> The advice (not the Modifier production) should change to give an exception
> for TYPE_USE annotations, recommending they be placed last:
>
>   private final @NonNull String s;
>
> I think this solves the problem of mixing TYPE_USE and non-TYPE_USE
> annotations, because the advice would imply:
>
>   @Deprecated private final @NonNull String s;
>
> Mike, Doug, any comments?
>
> Alex
>
> On 3/20/2013 11:28 AM, Srikanth S Adayapalam wrote:
> > Dear EG,
> >
> >	We have a request from the Eclipse JDT team that JSR308 should
> > constrain/require the position of TYPE_USE annotations in declaration
> > modifiers, so that all TYPE_USE annotations must be placed at the end
> > of the modifiers list. (Or in other words, where a type annotation features
> > in a place a declaration annotation aka a SE7 annotation can also feature,
> > the language should mandate that they be placed immediately preceding
> > the type which they are annotating.
> >
> > Example:
> >
> > package jsr308.bug;
> >
> > import java.lang.annotation.ElementType;
> > import java.lang.annotation.Target;
> >
> > @Target(ElementType.TYPE_USE)
> > @interface NonNull { }
> >
> > public class Bug {
> >		 @Deprecated @NonNull String s  = new @NonNull String();
> >		 @NonNull @Deprecated String s2 = new @NonNull String();  //
> > disallow
> > }
> >
> > The rationale being:
> >
> > A declaration like "@NonNull @Deprecated String" is hard to understand for
> > Java programmers. It doesn't make sense to allow the TYPE_USE annotation
> > to occur anywhere in the modifiers list. Unlike e.g. an ElementType.FIELD
> > annotation, a TYPE_USE annotation is not a general modifier of the
> > declaration.
> > A TYPE_USE annotation always belongs to the following type, so it should
> > also
> > be right in front of the type in the source.
> >
> > The main concern is that from a language point of view, it doesn't make
> > sense to tear apart the TYPE_USE annotation and the type proper. This
> > was possible with annotations that abused other ElementTypes to
> > implement a restricted form of TYPE_USE annotations. But that doesn't
> > mean it needs to stay this way.
> >
> > Thanks for considering this,
> > Srikanth.
>


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