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

Markus Keller markus_keller at ch.ibm.com
Fri Feb 7 02:51:11 PST 2014


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