[type-annos-observers] type annotations on generic method return type

Alex Buckley alex.buckley at oracle.com
Thu Feb 6 16:01:53 PST 2014


No, I meant "reject the @B". If you want it to be accepted, please 
provide an unambiguous JLS grammar for MethodHeader.

Alex

On 2/6/2014 3:59 PM, Werner Dietl wrote:
> Alex,
>
> In your last sentence:
>
>> I am therefore going to leave JLS8 as-is, and ask both compilers to
>> reject the @B after the type parameter section.
>
> don't you mean "accept the @B"?
> It would be quite ugly if we had to separate a type annotation on the
> return type by the type parameter section.
>
> cu, WMD.
>
>
> On 02/06/2014 06:43 PM, Alex Buckley wrote:
>> 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