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

Alex Buckley alex.buckley at oracle.com
Fri Feb 7 13:29:07 PST 2014


Since MethodHeader has been improved, it's possible to say simply:

InterfaceMethodDeclaration:
   {InterfaceMethodModifier} MethodHeader MethodBody

which is pleasingly consistent with MethodDeclaration.

Alex

On 2/7/2014 2:51 AM, Markus Keller wrote:
> Thanks Werner and Alex. I fully agree @B should be legal, and the proposed
> grammar looks OK to me.
>
> Note that InterfaceMethodDeclaration needs the same treatment:
>
> InterfaceMethodDeclaration:
>     {InterfaceMethodModifier} Result MethodDeclarator [Throws] MethodBody
>     {InterfaceMethodModifier} TypeParameters {Annotation} Result
> MethodDeclarator [Throws] MethodBody
>
>
> An alternative would be to move TypeParameters into Result, but I couldn't
> find a good name for the nonterminal:
>
> MethodHeader:
>     {MethodModifier} TypeParametersAndResult MethodDeclarator [Throws]
>
> InterfaceMethodDeclaration:
>     {InterfaceMethodModifier} TypeParametersAndResult MethodDeclarator
> [Throws] MethodBody
>
> TypeParametersAndResult:
>     TypeParameters {Annotation} UnannType
>     UnannType
>     [TypeParameters] void
>
> Although I still don't see a relevant use case for @A, I guess it makes
> sense to keep that legal (since the JLS also allows type annotations in
> similarly disconnected locations in other kinds of declarations).
>
> Markus
>
> Alex Buckley <alex.buckley at oracle.com> wrote on 2014-02-07 03:50:38:
>> From: Alex Buckley <alex.buckley at oracle.com>
>> To: Werner Dietl <wdietl at gmail.com>
>> Cc: type-annotations-spec-comments at openjdk.java.net
>> Date: 2014-02-07 03:52
>> Subject: Re: [type-annos-observers] type annotations on generic method
> return type
>> Sent by: type-annotations-spec-observers-bounces at openjdk.java.net
>>
>> I guess that works. Shades of MethodDeclarator - "Huh? There's an
>> {Annotation} nonterminal _there_?" - but it does the job. Good catch!
>>
>> I'd be inclined to pull MethodModifier up:
>>
>> MethodDeclaration:
>>     {MethodModifier} MethodHeader MethodBody
>>
>> MethodHeader:
>>     Result MethodDeclarator [Throws]
>>     TypeParameters {Annotation} Result MethodDeclarator [Throws]
>>
>> because that's more consistent with ClassDeclaration, FieldDeclaration,
>> et al. "Method header" may be an informal phrase in conversation, but
>> it's not actually used in the text.
>>
>> Alex
>>
>> On 2/6/2014 5:10 PM, Werner Dietl wrote:
>>> What would be bad about this:
>>>
>>> MethodHeader:
>>>     {MethodModifier} Result MethodDeclarator [Throws]
>>>     {MethodModifier} TypeParameters {Annotation} Result
> MethodDeclarator [Throws]
>>>
>>> If you don't like the "Result MethodDeclarator [Throws]" duplication,
>>> you could introduce a MethodHeaderRest for it.
>>>
>>> But maybe I misunderstand what ambiguity you mean.
>>>
>>> cu, WMD.
>>>
>>>
>>> On Thu, Feb 6, 2014 at 7:01 PM, Alex Buckley <alex.buckley at oracle.com>
> wrote:
>>>> 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