type annotations on generic method return type

Alex Buckley alex.buckley at oracle.com
Thu Feb 6 15:43:27 PST 2014


First of two mails. Not good news in this one.

On 2/6/2014 8:58 AM, Markus Keller wrote:
> What about a generic method declaration, where a type parameter
> declaration "<T>" separates the method modifiers from the return type's
> type annotations?
>
>      public @A <T> @B Set<T> foo(T t) { /*...*/ }
>
> => @B is _not_ syntactically legal according to the current grammar, since
> Result cannot start with an annotation:
>
> MethodHeader:
>          {MethodModifier} [TypeParameters] Result MethodDeclarator [Throws]
>
> Result:
>          UnannType
>          void
>
> Both javac and ecj currently accept the above declaration.

The original 308 spec (java-annotation-design.pdf) didn't address 
generic method declarations. Here are the relevant productions from JLS7 
ch.18:

ClassBodyDeclaration:
   ...
   {Modifier} MemberDecl

MemberDecl:
   GenericMethodOrConstructorDecl  // Not modified by 308
   MethodOrFieldDecl               // Modified by 308
   ...

// Modified by 308
MethodOrFieldDecl:
   UnannType Identifier MethodOrFieldRest

// Not modified by 308
GenericMethodOrConstructorDecl:
   TypeParameters GenericMethodOrConstructorRest

GenericMethodOrConstructorRest:
   (Type | void) Identifier MethodDeclaratorRest
   ...

Type:
   [Annotations] UnannType

The effect was to allow @B after the type parameter section:

   public <T> @B Set<T> foo(...) {...}

and of course @A as a modifier before the type parameter section:

   public @A <T> Set<T> foo(...) {...}

Ordinarily, I would change JLS8 to agree with that intent (albeit rather 
subtle) and with the behavior of both compilers. That is, I would regard 
this whole topic as a minor spec integration problem.

Unfortunately, JLS8 cannot be cleanly changed. The problem is the ch.8 
grammar for MethodHeader, distinct from the old ch.18 grammar. We cannot 
change MethodHeader to:

MethodHeader:
   {MethodModifier} [TypeParameters] {Annotation} Result ...

because, without no type parameters present, any annotations immediately 
to the left of Result would be ambiguous.

I am therefore going to leave JLS8 as-is, and ask both compilers to 
reject the @B after the type parameter section.

Alex


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