[type-annos-observers] 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-observers
mailing list