From mernst at cs.washington.edu Thu May 2 21:47:44 2013 From: mernst at cs.washington.edu (Michael Ernst) Date: Thu, 02 May 2013 21:47:44 -0700 (PDT) Subject: [type-annos-observers] May 2 version of the Type Annotations (JSR 308) Specification Message-ID: <20130502.214744.1724936846950125595.mernst@cs.washington.edu> A new version of the Type Annotations (JSR 308) Specification is available at http://types.cs.washington.edu/jsr308/specification/java-annotation-design.html http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf The changelog appears below. -Mike Grammar changes: Refactor JLS grammar to clarify that throws and catch clauses contain type uses that can be annotated, even though type parameters and arrays are forbidden in such locations. See the productions for QualifiedType, UnannQualifiedType, and QualifiedTypeList. Classfile changes: Remove unused target_info method_reference_target. Clarifications: Give examples of interaction between multiple @Target meta-annotations and fully-qualified type names. Explain why instanceof uses offset_target but cast uses type_argument_target. Move examples of classfile annotations, which are not normative, into an appendix so that Section 3 contains only normative text. From alex.buckley at oracle.com Fri May 3 14:35:50 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 03 May 2013 14:35:50 -0700 Subject: [type-annos-observers] Removing target_type distinctions between constructors and methods In-Reply-To: <20130417.072321.584038017916992251.mernst@cs.washington.edu> References: <20130417.072321.584038017916992251.mernst@cs.washington.edu> Message-ID: <51842DB6.3000801@oracle.com> I am fine with keeping the target_type values as they are. There are no ctors in a ClassFile, only methods, so type annotations connected with a ctor declaration are stored under a method_info. If the first table in figure 1 had a target_type 0x02 "constructor type parameter", would the method_info have to be an instance initialization method? (Repeat as necessary if the second table had target_type values for "constructor return type" et al.) Not worth checking. Core reflection can perfectly well understand that an annotated method type parameter for an instance initialization method should be exposed as an annotated constructor type parameter. Things are slightly trickier with the third table. A ctor invocation in the Code attributes differs significantly from a method invocation. We may yet see ctor reference expressions deviate in syntax or implementation from method reference expressions. Having distinct target_type values doesn't strike me as "wrong", so I'm happy to keep them. Alex On 4/17/2013 7:23 AM, Michael Ernst wrote: > Currently, the Type Annotations (JSR 308) Specification uses different > TargetType enum constants and target_type values for constructors and > methods. For example, here are target_type values: > > 0x45 constructor reference receiver > 0x46 method reference receiver > > 0x48 type argument in constructor call > 0x49 type argument in method call > > 0x4A type argument in constructor reference > 0x4B type argument in method reference > > These distinctions seem irrelevant. You can tell whether an annotation > relates to a constructor or method from where it appears in the class file, > so it doesn't seem to be necessary to also encode this in target_type. > > Perhaps these distinctions were put in the JSR 308 spec because an earlier > version of the lambda spec made these distinctions in its grammar (and > possibly elsewhere). > > I propose that we eliminate this distinction, using only 3 instead of 6 > target_type values and TargetType enum constants. I'd like to hear > reactions from others (both on and off the Expert Group) before making this > change, though. Thoughts? > > Thanks, > > -Mike From alex.buckley at oracle.com Fri May 3 14:38:44 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Fri, 03 May 2013 14:38:44 -0700 Subject: [type-annos-observers] May 2 version of the Type Annotations (JSR 308) Specification In-Reply-To: <20130502.214744.1724936846950125595.mernst@cs.washington.edu> References: <20130502.214744.1724936846950125595.mernst@cs.washington.edu> Message-ID: <51842E64.9060306@oracle.com> Please see the following four threads: - "Desugaring of anonymous classes" 3/31 - "JLS Creator production does not use 'Type'" 3/31 - "Clarifying the receiver parameter" 4/10 - "Removing target_type distinctions between constructors and methods" 4/17 The first three threads contain spec changes not found in the May 2 spec. Alex On 5/2/2013 9:47 PM, Michael Ernst wrote: > A new version of the Type Annotations (JSR 308) Specification is > available at > > http://types.cs.washington.edu/jsr308/specification/java-annotation-design.html > > http://types.cs.washington.edu/jsr308/specification/java-annotation-design.pdf > > > The changelog appears below. > > -Mike > > Grammar changes: > Refactor JLS grammar to clarify that throws and catch clauses contain > type uses that can be annotated, even though type parameters and arrays > are forbidden in such locations. See the productions for QualifiedType, > UnannQualifiedType, and QualifiedTypeList. > > Classfile changes: > Remove unused target_info method_reference_target. > > Clarifications: > Give examples of interaction between multiple @Target meta-annotations > and fully-qualified type names. > Explain why instanceof uses offset_target but cast uses > type_argument_target. > Move examples of classfile annotations, which are not normative, into an > appendix so that Section 3 contains only normative text. From jonathan.gibbons at oracle.com Fri May 3 14:50:13 2013 From: jonathan.gibbons at oracle.com (Jonathan Gibbons) Date: Fri, 03 May 2013 14:50:13 -0700 Subject: [type-annos-observers] Removing target_type distinctions between constructors and methods In-Reply-To: <51842DB6.3000801@oracle.com> References: <20130417.072321.584038017916992251.mernst@cs.washington.edu> <51842DB6.3000801@oracle.com> Message-ID: <51843115.6070704@oracle.com> If the values are distinct for constructor and method, that implies someone would have to check them, meaning that someone would have to check things like "0x46 method reference receiver" was not used on an method, etc. Simpler is better, as long as it really is simpler overall. -- Jon On 05/03/2013 02:35 PM, Alex Buckley wrote: > I am fine with keeping the target_type values as they are. > > There are no ctors in a ClassFile, only methods, so type annotations > connected with a ctor declaration are stored under a method_info. If > the first table in figure 1 had a target_type 0x02 "constructor type > parameter", would the method_info have to be an instance > initialization method? (Repeat as necessary if the second table had > target_type values for "constructor return type" et al.) Not worth > checking. Core reflection can perfectly well understand that an > annotated method type parameter for an instance initialization method > should be exposed as an annotated constructor type parameter. > > Things are slightly trickier with the third table. A ctor invocation > in the Code attributes differs significantly from a method invocation. > We may yet see ctor reference expressions deviate in syntax or > implementation from method reference expressions. Having distinct > target_type values doesn't strike me as "wrong", so I'm happy to keep > them. > > Alex > > On 4/17/2013 7:23 AM, Michael Ernst wrote: >> Currently, the Type Annotations (JSR 308) Specification uses different >> TargetType enum constants and target_type values for constructors and >> methods. For example, here are target_type values: >> >> 0x45 constructor reference receiver >> 0x46 method reference receiver >> >> 0x48 type argument in constructor call >> 0x49 type argument in method call >> >> 0x4A type argument in constructor reference >> 0x4B type argument in method reference >> >> These distinctions seem irrelevant. You can tell whether an annotation >> relates to a constructor or method from where it appears in the class >> file, >> so it doesn't seem to be necessary to also encode this in target_type. >> >> Perhaps these distinctions were put in the JSR 308 spec because an >> earlier >> version of the lambda spec made these distinctions in its grammar (and >> possibly elsewhere). >> >> I propose that we eliminate this distinction, using only 3 instead of 6 >> target_type values and TargetType enum constants. I'd like to hear >> reactions from others (both on and off the Expert Group) before >> making this >> change, though. Thoughts? >> >> Thanks, >> >> -Mike From markus_keller at ch.ibm.com Mon May 6 03:49:14 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Mon, 6 May 2013 12:49:14 +0200 Subject: [type-annos-observers] RetentionPolicy.CLASS too broad for TYPE_USE annotations Message-ID: The RetentionPolicy.CLASS looks too broad for many TYPE_USE annotations. For annotations that are meant to serve as API contracts, it's enough to include the externally visible annotations (target_type values 0x1*) in the class file. The internal annotations (0x4*) are not interesting for this use case and only bloat the class file. Neither the user who compiles the code nor the provider of a TYPE_USE annotation currently have the means to selectively enable retention only for the interesting group. I see two possible solutions to this problem: 1) Compilers offer an opt-in mechanism to store internal annotations. Similar to JEP 118's proposed "-parameters" command-line switch, this could be called "-internalAnnotations". 2) Introduce new RetentionPolicy values CLASS_INTERNAL and RUNTIME_INTERNAL to tell that non-visible annotations should be stored in the class file as well. The existing CLASS and RUNTIME policies could be kept for externally visible annotations only (the main use case). The suffix could also be "_INCLUDING_CODE_BLOCKS". With both solutions, e.g. an @NonNull annotation could stay at @Retention(RetentionPolicy.CLASS). Markus From joe.darcy at oracle.com Wed May 22 22:07:24 2013 From: joe.darcy at oracle.com (Joe Darcy) Date: Wed, 22 May 2013 22:07:24 -0700 Subject: [type-annos-observers] FYI, JSR 308 and the annotation processing discovery process In-Reply-To: <515A5C52.50907@oracle.com> References: <5155291F.2050907@oracle.com> <51561161.8030207@oracle.com> <515A5C52.50907@oracle.com> Message-ID: <519DA40C.9090703@oracle.com> Hello, An update on updating annotation processing discovery to account for the annotation changes made in JSR 308 (type annotations and declaration annotations on type parameters) as well as repeating annotations: the proposed specification change is: @@ -88,7 +90,8 @@ * configuration mechanisms, such as command line options; for * details, refer to the particular tool's documentation. Which * processors the tool asks to {@linkplain #process run} is a function - * of what annotations are present on the {@linkplain + * of the types of the annotations {@linkplain AnnotatedConstruct present} + * on the {@linkplain * RoundEnvironment#getRootElements root elements}, what {@linkplain * #getSupportedAnnotationTypes annotation types a processor * processes}, and whether or not a processor {@linkplain #process @@ -106,6 +109,28 @@ * processing {@code "*"} can claim the (empty) set of annotation * types. * + *

An annotation type is considered present if there is at least + * one annotation of that type present on an element enclosed within + * the root elements of a round. Annotations on {@linkplain + * ElementType#TYPE_USE type uses} are not considered as part + * of the computation. For this purpose, a type parameter is + * considered to be enclosed by its {@linkplain + * TypeParameter#getGenericElement generic element}. An annotation is + * present if it meets the definition of being present given in {@link + * AnnotatedConstruct}. In brief, an annotation is considered present + * for the purposes of discovery if it is directly present or present + * via inheritance. An annotation is not considered present + * by virtue of being wrapped by a container + * annotation. Operationally, this is equivalent to an annotation + * being present on an element if and only if it would be included in + * the results of {@link Elements#getAllAnnotationMirrors()} called on + * that element. Since annotations inside container annotations are + * not considered present, to properly process {@linkplain + * java.lang.annotation.Repeatable repeatable annotation types}, + * processors are advised to include both the annotation and its + * container in the set of {@linkplain #getSupportedAnnotationTypes() + * supported annotation types} of a processor. + * *

Note that if a processor supports {@code "*"} and returns {@code * true}, all annotations are claimed. Therefore, a universal * processor being used to, for example, implement additional validity For more context, the webrev (which includes implementation changes) is at: http://cr.openjdk.java.net/~darcy/7162089.2/ Thanks, -Joe On 04/01/2013 09:19 PM, Joe Darcy wrote: > On 03/29/2013 03:10 PM, Alex Buckley wrote: >> On 3/28/2013 10:39 PM, Joe Darcy wrote: >>> FYI, as the JSR 269 maintenance lead, besides updating the >>> javax.lang.model.* API to handle new-in-Java-SE-8 features, I'm not >>> looking at updating the javax.annotation.processing API to deal with >>> those new annotation-related features too. >> >> "not looking"? Surely "now looking". > > Quite! > >> >>> "The tool uses a discovery process to find annotation processors and >>> decide whether or not they should be run. [...] Which processors the >>> tool asks to run is a function of what annotations are present on the >>> root elements, what annotation types a processor processes, and whether >>> or not a processor claims the annotations it processes. [...] For a >>> given round, the tool computes the set of annotation types on the root >>> elements. If there is at least one annotation type present, as >>> processors claim annotation types, they are removed from the set of >>> unmatched annotations." >> >> Close reading of the above paragraph reveals that: >> >> - a processor _claims_ annotation types >> - a processor _claims_ annotations >> - a processor _processes_ annotations >> - from a set of annotations, it is possible to remove annotation _types_ >> >> I contend there is at least one kind error going on here. > > I will tighten up the wording accordingly; thanks for the careful > reading. > >> >>> To this, I plan to add a paragraph explaining how type annotations do >>> not interact with the this discovery process; something like: >>> >>> "

An annotation type is considered present if there is at least one >>> annotation of that type on a declaration enclosed within the root >>> elements of a round. For this purpose, a type parameter is considered >>> to be enclosed by its generic element. Annotations on type uses are >>> not considered as part of the computation. >> >> There is quite a phase shift between the "For this purpose" sentence >> and the type uses sentence. I think a new paragraph is warranted: >> "Annotations on type uses are ignored when computing the set of >> annotation types present on the root elements." >> >>> For the purposes of JSR 308: >>> >>> * Declaration annotations on type parameters are included in discovery >>> * TYPE_USE annotations are *not* included as part of discovery >> >> You mean to put "For the purposes of JSR 308" into the SE 8 API spec? > > No. "For the purposes of JSR 308" is just for the purposes of this > email thread :-) > >> That would be wrong, as a JSR number is pure administration and the >> API spec should deal only in features. > > Agreed. > >> >> For the bullet points, beware: an annotation whose type targets >> TYPE_USE can appear on a type declaration or a type parameter >> declaration. Surely you want such an annotation on class Foo's >> declaration to be discovered. Do you mean: >> >> - Annotations on type parameter declarations are included in discovery. >> - Annotations on type uses are not included in discovery. >> >> > > Annotations on declarations, including declarations of type > parameters, are included in discovery. > > -Joe > From alex.buckley at oracle.com Thu May 23 11:59:45 2013 From: alex.buckley at oracle.com (Alex Buckley) Date: Thu, 23 May 2013 11:59:45 -0700 Subject: [type-annos-observers] FYI, JSR 308 and the annotation processing discovery process In-Reply-To: <519DA40C.9090703@oracle.com> References: <5155291F.2050907@oracle.com> <51561161.8030207@oracle.com> <515A5C52.50907@oracle.com> <519DA40C.9090703@oracle.com> Message-ID: <519E6721.80906@oracle.com> Thanks very much Joe. Some distressingly tricky stuff below: On 5/22/2013 10:07 PM, Joe Darcy wrote: > @@ -88,7 +90,8 @@ > * configuration mechanisms, such as command line options; for > * details, refer to the particular tool's documentation. Which > * processors the tool asks to {@linkplain #process run} is a function > - * of what annotations are present on the {@linkplain > + * of the types of the annotations {@linkplain AnnotatedConstruct > present} > + * on the {@linkplain > * RoundEnvironment#getRootElements root elements}, what {@linkplain > * #getSupportedAnnotationTypes annotation types a processor > * processes}, and whether or not a processor {@linkplain #process > @@ -106,6 +109,28 @@ It would be clearer and more kind-correct to say: "Which processors the tool asks to run is a function of i) the types of the annotations present on the root elements, ii) the annotation types supported by a processor, and iii) the annotation types claimed by a processor." The idea that a processor CLAIMS annotation types comes from line 104. And if this is right, Processor#process must be clarified. It takes a set of types - great - and returns whether the processor claims all annotations of those types. If you intend to draw an equivalence between "claiming all annotations of types X and Y" and "claiming the annotation types X and Y", please be explicit about it. Right now, the following method spec simply does not parse: "Processes a set of ANNOTATION TYPES on type elements originating from the prior round and returns whether or not THESE ANNOTATIONS are claimed by this processor." It would also be good to say "(see below)" when line 104 introduces the idea of annotation types being present, since the more common concept is of annotations being present. OK, moving to the new text... > + *

An annotation type is considered present if there is at least > + * one annotation of that type present on an element enclosed within > + * the root elements of a round. > + * Annotations on {@linkplain > + * ElementType#TYPE_USE type uses} are not considered as part > + * of the computation. An annotation might be able to target type uses _and_ traditional declaration locations. I think you want to ignore annotations which are _solely_ interested in targeting type uses. At the same time, remember that ElementType.TYPE_USE means "type uses _and_ type declarations and type parameter declarations". So, given an annotation type Foo with @Target(TYPE_USE) and no other @Target, would @Foo being present on a type declaration mean that annotation type Foo is present? The answer should be "yes", because the intent of ElementType.TYPE_USE is to supersede ElementType.TYPE (no doubt the prior @Target of Foo) and previous annotation processors would have processed @Foo on a type declaration just fine. BTW, line 102 should say "the tool computes the set of annotation types PRESENT on the root elements." > + * For this purpose, a type parameter is > + * considered to be enclosed by its {@linkplain > + * TypeParameter#getGenericElement generic element}. Big context switch here from type-oriented stuff to element-oriented. Please put it in in TypeParameterElement's spec. Please have a paragraph break before the "annotation is present" stuff. > + * An annotation is > + * present if it meets the definition of being present given in {@link > + * AnnotatedConstruct}. In brief, an annotation is considered present > + * for the purposes of discovery if it is directly present or present > + * via inheritance. An annotation is not considered present > + * by virtue of being wrapped by a container > + * annotation. Operationally, this is equivalent to an annotation > + * being present on an element if and only if it would be included in > + * the results of {@link Elements#getAllAnnotationMirrors()} called on > + * that element. Since annotations inside container annotations are > + * not considered present, to properly process {@linkplain > + * java.lang.annotation.Repeatable repeatable annotation types}, > + * processors are advised to include both the annotation and its > + * container in the set of {@linkplain #getSupportedAnnotationTypes() > + * supported annotation types} of a processor. This was going great until: "advised to include both the annotation and its container in the set of ..." - it should be "include both the repeatable annotation type and its containing annotation type in the set of ...". Alex