From alex.buckley at oracle.com Mon Aug 5 17:00:12 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 05 Aug 2013 17:00:12 -0700 Subject: Desugaring of anonymous classes In-Reply-To: <5159E70D.2040702@oracle.com> References: <20130331.113913.2061923468052370653.mernst@cs.washington.edu> <5159E70D.2040702@oracle.com> Message-ID: <52003C8C.2010901@oracle.com> Mike, Srikanth, Returning to this topic, there are two scenarios where I would like your comments: 1. Type annotation in 'new' expression for anonymous class Consider this code: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE_USE) @interface X {} class C { void m() { new @X Foo() {}; } } The @X annotation is stored as a target_type=CLASS_EXTENDS structure in the RuntimeVisibleTypeAnnotations attribute of Foo$1.class. That's fine. The @X annotation is not stored as a target_type=NEW structure in the RuntimeVisibleTypeAnnotations attribute of m's method_info in C.class. That's an oversight by javac, especially since the first mail in this thread said javac copied type annotations "to the class declaration and to its instantiation (new expression)". 2. Declaration annotation for anonymous class in 'new' expression Take the code above and change the annotation type's target to be TYPE: @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.TYPE) @interface X {} class C { void m() { new @X Foo() {}; } } The @X annotation is stored in the RuntimeVisibleAnnotations structure of Foo$1.class. This is a neat trick, since anonymous class declarations could not be annotated in SE 7, but it is irregular because annotations on declarations traditionally appear as modifiers. If a 'new' expression is to provide a declaration context (for TYPE annotations) as well as a type context (for TYPE_USE annotations), then the spec needs to spell it out. What's more, annotations on anonymous class declarations could have implications for core reflection and other language features. It appears that "new @X @X Foo() {};" works at compile-time, but I have not tried reflecting over Foo$1.class's RuntimeVisibleAnnotations attribute. Alex On 4/1/2013 12:59 PM, Alex Buckley wrote: > On 3/31/2013 11:39 AM, Michael Ernst wrote: >> In January, I removed the text from the specification that was >> compiler-specific. This text was among the removed text: >> >> As another example, an anonymous class desugars into a class >> declaration >> and instantiation. A programmer may write both type and declaration >> annotations on an anonymous class in Java source code. In the >> classfile, >> the type annotations are copied to the class declaration and to its >> instantiation (new expression). The declaration annotations are >> copied >> only to the class declaration. >> >> Do you consider this possibly implementation-specific, and therefore it >> does not belong in the specification. Or, will every compiler follow >> this >> implementation strategy so it is worth re-instating as useful guidance? > > It would be better to start with the concept of a class instance > creation expression (CICE) since it lets the locations be more precise. > > A CICE may create an instance of an anonymous class, in which case the > declaration of the anonymous class is provided inline. This declaration > is required by JLS 13.1 to compile to a form with a binary name; you can > take this to mean a standalone class file is emitted. > > A CICE may have i) type annotations in the 'new ... {' term outside the > anonymous class declaration, and ii) type annotations and declaration > annotations inside the anonymous class declaration. It would be > appropriate to specify: > > - The (i) annotations (type only) are stored for the CICE in its > enclosing class file _and_ stored for the superclass of the anonymous > class declaration in its emitted class file. > > - The (ii) annotations (type and decl) are stored for the appropriate > type uses and declarations in the class file emitted for the anonymous > class declaration. > > Alex From alex.buckley at oracle.com Mon Aug 5 18:36:25 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Mon, 05 Aug 2013 18:36:25 -0700 Subject: JLS and JVMS changes for JSR 308 Message-ID: <52005319.9000209@oracle.com> I have prepared a PDF containing the JLS and JVMS changes for JSR 308: http://cr.openjdk.java.net/~abuckley/308.pdf If you're expecting a simple list of grammar changes, you may want to sit down before opening the PDF. There are significant clarifications to JLS chapters 4 and 6, all aimed at pinning down what exactly is a type use. The JLS has distinguished between types (a.k.a. type uses) and type names since JLS3, but it was very subtle, and it is essential for JLS8 to take a comprehensive view of the language's syntactic contexts and the types and names allowed therein. The ClassFile changes present a recurring challenge: how much to mention Java language features in the JVMS? The Signature attribute is a precedent, so for now, I have aimed for maximum clarity. An example would be mentioning both constructors and methods when describing target_info, even though the ClassFile structure is aware only of methods. Text in the PDF is either normative or informative. Informative text is smaller and indented. The point of the PDF is that most text is ready to go into the JLS or JVMS as-is, although informative text which mentions JSR 308 is intended more as commentary for 2013 than as long-term specification; it will evolve further, or be removed. The UW PDF at: http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf remains an excellent source of background, examples, and rationale. This kind of material should be available on the JSR 308 page at jcp.org forever, so I envisage offering both 308.pdf and java-annotation-design.pdf in the milestone reviews yet to come. Mike, it would be instructive to look at how JSR 334's specification changed between Public Review and Proposed Final Draft. Vast swathes of normative text were replaced with pointers to JLS sections. It would be appropriate to start the same "pruning" process on java-annotation-design.pdf. This will provide a double check on my extraction of normative clauses from java-annotation-design.pdf. Alex From srikanth_sankaran at in.ibm.com Fri Aug 23 02:33:37 2013 From: srikanth_sankaran at in.ibm.com (Srikanth S Adayapalam) Date: Fri, 23 Aug 2013 15:03:37 +0530 Subject: Desugaring of anonymous classes In-Reply-To: <52003C8C.2010901@oracle.com> References: <20130331.113913.2061923468052370653.mernst@cs.washington.edu> <5159E70D.2040702@oracle.com> <52003C8C.2010901@oracle.com> Message-ID: > From: Alex Buckley > Sent by: type-annotations-spec-experts-bounces at openjdk.java.net > > Mike, Srikanth, > > Returning to this topic, there are two scenarios where I would like your > comments: Hi Alex, First of all, apologies for the delay in responding. > 1. Type annotation in 'new' expression for anonymous class > > Consider this code: > > @Retention(RetentionPolicy.RUNTIME) > @Target(ElementType.TYPE_USE) > @interface X {} > > class C { void m() { new @X Foo() {}; } } > > The @X annotation is stored as a target_type=CLASS_EXTENDS structure in > the RuntimeVisibleTypeAnnotations attribute of Foo$1.class. That's fine. I am fine with this behavior, though as there is nothing in the latest specification that calls for such a behavior, we should make sure to spell this out, if this is the behavior we want. > The @X annotation is not stored as a target_type=NEW structure in the > RuntimeVisibleTypeAnnotations attribute of m's method_info in C.class. > That's an oversight by javac, especially since the first mail in this > thread said javac copied type annotations "to the class declaration and > to its instantiation (new expression)". At the moment, eclipse compiler's behavior is the exact opposite of what you mention as javac's behavior. We emit the annotation with target_type being NEW but not target_type=CLASS_EXTENDS. > 2. Declaration annotation for anonymous class in 'new' expression > > Take the code above and change the annotation type's target to be TYPE: > > @Retention(RetentionPolicy.RUNTIME) > @Target(ElementType.TYPE) > @interface X {} > > class C { void m() { new @X Foo() {}; } } > > The @X annotation is stored in the RuntimeVisibleAnnotations structure > of Foo$1.class. This is a neat trick, since anonymous class declarations > could not be annotated in SE 7, but it is irregular because annotations > on declarations traditionally appear as modifiers. If a 'new' expression This is more irregular than neat and I would be inclined to suggest that we pull back such behavior. At the moment again, as you call out there is nothing in the specification that calls for such a behavior. Srikanth, From alex.buckley at oracle.com Fri Aug 23 12:04:56 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 23 Aug 2013 12:04:56 -0700 Subject: Desugaring of anonymous classes In-Reply-To: References: <20130331.113913.2061923468052370653.mernst@cs.washington.edu> <5159E70D.2040702@oracle.com> <52003C8C.2010901@oracle.com> Message-ID: <5217B258.80402@oracle.com> Hi Srikanth, On 8/23/2013 2:33 AM, Srikanth S Adayapalam wrote: > > 1. Type annotation in 'new' expression for anonymous class > > > > Consider this code: > > > > @Retention(RetentionPolicy.RUNTIME) > > @Target(ElementType.TYPE_USE) > > @interface X {} > > > > class C { void m() { new @X Foo() {}; } } > > > > The @X annotation is stored as a target_type=CLASS_EXTENDS structure in > > the RuntimeVisibleTypeAnnotations attribute of Foo$1.class. That's fine. > > I am fine with this behavior, though as there is nothing in the latest > specification that calls for such a behavior, we should make sure to > spell this out, if this is the behavior we want. Foo is, of course, the direct superclass of the anonymous class (JLS 15.9.1), but the 'extends' clause is hard to see in the code above. The wording for target_type=CLASS_EXTENDS (0x10) refers to a "type in extends clause of class or interface declaration" so it's not clear that the @X annotation should be stored this way. To clarify, the wording for target_type=CLASS_EXTENDS should say: "type in extends clause of class or interface declaration (including the direct superclass of an anonymous class declaration), ..." > > The @X annotation is not stored as a target_type=NEW structure in the > > RuntimeVisibleTypeAnnotations attribute of m's method_info in C.class. > > That's an oversight by javac, especially since the first mail in this > > thread said javac copied type annotations "to the class declaration and > > to its instantiation (new expression)". > > At the moment, eclipse compiler's behavior is the exact opposite of what > you mention as javac's behavior. We emit the annotation with target_type > being NEW but not target_type=CLASS_EXTENDS. I will file a bug for javac to emit the target_type=NEW attribute. Then if ecj can emit the target_type=CLASS_EXTENDS, everything will be good. > > 2. Declaration annotation for anonymous class in 'new' expression > > > > Take the code above and change the annotation type's target to be TYPE: > > > > @Retention(RetentionPolicy.RUNTIME) > > @Target(ElementType.TYPE) > > @interface X {} > > > > class C { void m() { new @X Foo() {}; } } > > > > The @X annotation is stored in the RuntimeVisibleAnnotations structure > > of Foo$1.class. This is a neat trick, since anonymous class declarations > > could not be annotated in SE 7, but it is irregular because annotations > > on declarations traditionally appear as modifiers. If a 'new' expression > > This is more irregular than neat and I would be inclined to suggest that > we pull back such behavior. At the moment again, as you call out there is > nothing in the specification that calls for such a behavior. Thanks for this comment. I will file a bug for javac to remove the RuntimeVisibleAnnotations attribute. In the recent JLS/JVMS draft for JSR 308, the above code is illegal: a 'new' expression is a "type context", and "It is a compile-time error if an annotation of type T decorates a type in a type context (4.11), but T is not applicable to type uses." ... the annotation type X is not applicable to type uses because "The constants ... TYPE ... correspond to the declaration contexts ...". Alex From alex.buckley at oracle.com Fri Aug 23 15:49:47 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 23 Aug 2013 15:49:47 -0700 Subject: Storing declaration annotations on a local variable In-Reply-To: References: Message-ID: <5217E70B.1010809@oracle.com> For the record, it is too late for JSR 308 to consider storing declaration annotations on local variables. Alex -------- Original Message -------- Subject: Storing declaration annotations on a local variable Date: Mon, 18 Feb 2013 01:03:26 -0800 From: Werner Dietl To: type-annotations-spec-comments at openjdk.java.net Java 1.5 declaration annotations on local variables can be written, but are not stored in the bytecode. Java 1.8 type annotations on a local variable are stored in the bytecode. Should we store declaration annotations on local variables together with type annotations on local variables? Let's assume a declaration annotation @DA, a type annotation @TA, and this code: class Test { @TA @DA Object f = null; void foo() { @TA @DA Object l = null; } } A fragment of the output of javap -v is: java.lang.Object f; descriptor: Ljava/lang/Object; flags: RuntimeInvisibleAnnotations: 0: #8() RuntimeInvisibleTypeAnnotations: 0: #10(): FIELD ... void foo(); descriptor: ()V ... RuntimeInvisibleTypeAnnotations: 0: #10(): LOCAL_VARIABLE, {start_pc=2, length=1, index=1} (Where #8 is @DA and #10 is @TA.) That is, as expected, the field has both the declaration and the type annotation, whereas the local variable only stores the type annotation. Storing declaration annotations for local variables will enable more use cases for declaration annotations and make the language more consistent. It should be very simple to store the declaration annotation together with the type annotation, giving something like: RuntimeInvisibleTypeAnnotations: 0: #8(): LOCAL_VARIABLE, {start_pc=2, length=1, index=1} 1: #10(): LOCAL_VARIABLE, {start_pc=2, length=1, index=1} The obvious disadvantage being that we would now mix type and declaration annotations. Instead, with a bit more work, we could introduce a RuntimeInvisibleLocalVariableAnnotation that is used just for this purpose. It would use the same format as for type annotations on local variables and should be straightforward to implement. The reflection API will not be extended to expose these declaration annotations on local variables. What do you think of this proposal? cu, WMD. -- http://www.google.com/profiles/wdietl