From markus_keller at ch.ibm.com Tue Oct 15 13:10:15 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Tue, 15 Oct 2013 22:10:15 +0200 Subject: [type-annos-observers] RetentionPolicy.CLASS too broad for TYPE_USE annotations ? In-Reply-To: <525D8256.3020306@oracle.com> References: <525D8256.3020306@oracle.com> Message-ID: Alex Buckley wrote on 2013-10-15 19:58:46 to type-annotations-spec-experts & type-annotations-spec-observers: > Markus' mail went unanswered because it was sent to a list that the EG > does not generally follow. From the listinfo page for > type-annotations-spec-observers: > > "Members of the JSR 308 Expert Group are not required to follow traffic > on this list. Questions for the Expert Group about the design and > specification of JSR 308 may be sent to the > type-annotations-spec-comments list." Sorry for using the wrong list. I was subscribed to the observers list and assumed that a message to the Reply-To: address of your original mail would also reach you. Could you please have a look at these? Shouldn't be too late for that. http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2013-August/000179.html http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2013-October/000208.html Thanks, Markus From markus_keller at ch.ibm.com Mon Oct 21 08:32:16 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Mon, 21 Oct 2013 17:32:16 +0200 Subject: "final" ReceiverParameter? (was: Public Review for JSR 308) In-Reply-To: <525EDBC6.3030101@oracle.com> References: <525EDBC6.3030101@oracle.com> Message-ID: Alex Buckley wrote on 2013-10-16 20:32:38: > http://cr.openjdk.java.net/~abuckley/308.pdf Two more nits: 1. ReceiverParameter: {VariableModifier} UnannType {Identifier .} this VariableModifier syntactically allows annotations and "final". I don't think "final" makes sense here, not even optional. {VariableModifier} would better be replaced by {Annotation}. Otherwise, we'd need some spec text that tells that "final" is not a legal modifier for a receiver parameter. 2. Typo on p.18: "that type is the type is the newly constructed object" => 2nd "is" should be "of" ^^ Markus From markus_keller at ch.ibm.com Tue Oct 22 09:49:00 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Tue, 22 Oct 2013 18:49:00 +0200 Subject: Clarifying the receiver parameter In-Reply-To: <525DC83D.4040104@oracle.com> References: <525D8256.3020306@oracle.com> <525DC83D.4040104@oracle.com> Message-ID: Alex Buckley wrote on 2013-10-16 00:57:01: > On 10/15/2013 1:10 PM, Markus Keller wrote: > > Could you please have a look at these? Shouldn't be too late for that. > > http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2013-August/000179.html > > 1. The name of a receiver parameter in the draft is allowed to be 'this' > or the text of a qualified expression indicating the same class. I > raised this issue with the EG on April 10 ("Clarifying the receiver > parameter") because the 308 design document gave only an example. > Srikanth asked for rationale; I gave it. No-one else commented despite > my best efforts to highlight the semi-open thread at later dates. I wrote this answer to the observers list (another one lost in the mailing lists jungle): http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2013-April/000153.html I still think it would be better not to mix the declaration of a 'this' parameter with the qualified 'this' expression syntax. Markus From markus_keller at ch.ibm.com Tue Oct 22 11:04:50 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Tue, 22 Oct 2013 20:04:50 +0200 Subject: @Target mixing TYPE_USE and declaration annotation In-Reply-To: <525EDBC6.3030101@oracle.com> References: <525EDBC6.3030101@oracle.com> Message-ID: To finish the series of mails lost in the maligned observers list, I want to mention http://mail.openjdk.java.net/pipermail/type-annotations-spec-observers/2013-April/000152.html The gist is that allowing @Target annotations with a mixture of TYPE_USE and declaration elements is not only bad for implementers of annotation processors, but also for users of such annotations. I'm still convinced that mixing TYPE_USE with other targets should be forbidden. Page 20 of 308-20131016.pdf has such an example: > ------- If TA is additionally meta-annotated with @Target(ElementType.FIELD), then the term @TA java.lang.Object is legal in locations which are both declaration and type contexts, such as a field declaration @TA java.lang.Object f;. Here, @TA is deemed to apply to the declaration of f (and not to the type java.lang.Object) because TA is applicable in the field declaration context. > ------- Because an annotation can only have a single @Target annotation, the beginning would better be written as: "If TA is meta-annotated with @Target({ElementType.TYPE_USE, ElementType.FIELD}), ...". And the example hides the even worse ramifications for array-typed fields: @TA Object[] f2; The SE 7 APIs consider @TA an annotation on field f2. The SE 8 APIs consider @TA also a type annotation on Object (not on the field type Object[]!). Now what does that mean e.g. for "@Nullable Object[] f2;"? If an annotation processor wants to be source-compatible with SE 7 code, then it cannot rely on the SE 8 meaning of such a mixed-target annotation! Although the 308 spec attaches the type annotation to the type "Object", the annotation processor still has to adhere to the legacy meaning and must attach it to "Object[]". I.e. it effectively *cannot* make use of the added TYPE_USE element type in this case. If an annotation provider doesn't care about these corner cases with qualified and array types, then he can just switch to @Target(TYPE_USE). Otherwise, he should deprecate the old declaration annotation and declare a new type annotation. The current JSR 308 proposal doesn't tell that mixing target elements is considered bad style nor that it is discouraged. http://types.cs.washington.edu/jsr308/specification/java-annotation-design.html says: > Note from the above examples that a programmer is permitted to write can write a @Target meta-annotation indicating that an annotation, such as @FTAnno or @MTAnno, is both a type annotation and a declaration annotation. We have not found an example where such a meta-annotation is desirable for a newly-created annotation; although it is legal, it is considered bad style. By contrast, when migrating from Java SE 7 and older annotation processors to Java SE 8 and newer annotation processors, it may be desirable for the annotation to be both a type annotation and a declaration annotation, for reasons of backward compatibility. The last sentence about migration was only added in the very last revision, and it gives a very bad advice that locks annotation providers and users into an eternal backwards-compatibility mode. Summary: The spec allows a bad style for compatibility reasons, but it effectively fails to deliver that promise. Backwards compatibility and correct treatment of TYPE_USE exclude each other, and the spec should not make it appear like there is a solution. If it's too late for this change, then the spec should at least tell that mixed-target annotation types are dangerous and discouraged. Markus From markus_keller at ch.ibm.com Wed Oct 23 03:47:08 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Wed, 23 Oct 2013 12:47:08 +0200 Subject: Clarifying the receiver parameter (qualified 'this') In-Reply-To: <20131022.102906.1518626036282809992.mernst@cs.washington.edu> References: <525DC83D.4040104@oracle.com> <20131022.101107.1682533952140077700.mernst@cs.washington.edu> <20131022.102906.1518626036282809992.mernst@cs.washington.edu> Message-ID: In reply to Michael Ernst 's http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-October/000159.html Yes, we're not at all questioning the "Outer.this" notation for inner class constructors. I just find it awkward that the 308.pdf replaced java-annotation-design.html's [Identifier .] this with {Identifier .} this and allows (fully-)qualified 'this' expressions as the name of the receiver parameter even where that's not necessary. The argument about analogy to qualified 'this' expressions in a method body is IMO too far-fetched, since the receiver parameter is closer to being a declaration rather than a reference. By the same argument, you would also have to allow other names in declarations to be redundantly qualified, e.g.: package my.pack; public class my.pack.Example { // illegal (good) my.pack.Example() { } // illegal (good) void my.pack.Example.foo() { } // illegal (good) void bar(@Const Example my.pack.Example.this) { } // should be illegal } Markus From markus_keller at ch.ibm.com Thu Oct 24 05:56:15 2013 From: markus_keller at ch.ibm.com (Markus Keller) Date: Thu, 24 Oct 2013 14:56:15 +0200 Subject: Clarifying the receiver parameter (qualified 'this') In-Reply-To: <20131023.143410.529884525787026761.mernst@cs.washington.edu> References: <20131022.101107.1682533952140077700.mernst@cs.washington.edu> <20131022.102906.1518626036282809992.mernst@cs.washington.edu> <20131023.143410.529884525787026761.mernst@cs.washington.edu> Message-ID: Michael Ernst wrote on 2013-10-23 23:34:10: > First, the change from > [Identifier .] this > to > {Identifier .} this > was essential. The reason is that inside a doubly-nested inner class, the > receiver can have a name like Outer.Middle.this. Nope, Middle.this is always equivalent to Outer.Middle.this, so the "Outer." is never necessary. Example: package p; class Outer { class Middle { void m() {} class Inner { @I Inner(pack. at O Outer. at M Middle Middle.this, Middle m) { m.m(); Middle.this.m(); } } } } class Middle { // nasty, but legal void foo() {} } The annotations are on the receiver parameter's type, not on its name, so the 'this' doesn't have to be qualified with more than the immediately enclosing class. By the scoping rules, the name of an enclosing member type can always be referenced with a simple name. I don't buy the argument that allowing a fully-qualified 'this' makes the spec simpler. On the contrary: The "8.4.1 Formal Parameters" section in 308.pdf is full of little errors: "The receiver parameter of an instance method or inner class constructor is an optional syntactic device to represent the object for which the method or constructor is invoked." => For inner class constructors, the receiver parameter represents the immediately enclosing instance of the constructed object, not the object for which the constructor is invoked. "The name of the receiver parameter must either be 'this', or the text of a qualified 'this' expression (15.8.3) which would, if present in the body of the method or constructor, denote the class of the method or constructor's receiver; otherwise, a compile-time error occurs." => The "either ... or" doesn't make it clear that an unqualified 'this' cannot be used as the receiver parameter of an inner class constructor. "The type of the receiver parameter must be the class or interface in which the method or constructor is declared; otherwise, a compile-time error occurs." => For an inner class constructor, the type of the receiver parameter is _not_ the declaring type of the constructor (which would be the inner class), but it's the immediately enclosing class of the inner class. The Java language should stay as simple as possible. Here, the unrestricted qualifications even confused the spec authors. The straightforward approach with two separate cases for instance methods and for inner class constructors is much easier to handle. Why add code to check whether a qualified 'this' is legal when you can just exclude it in the grammar? The fully-qualified 'this' adds more complexity to the language, not less. Alex Buckley wrote on 2013-10-23 20:27:25: > The receiver parameter is _not_ "closer to being a declaration", The receiver parameter indeed doesn't declare a variable, but it's an explicit declaration for the otherwise implicitly declared "this" or "Outer.this" object. The declaration declares the annotated type of the 'this' object. Another similar example is a public no-args constructor declaration, which makes the implicit default constructor explicit. References can use a fully-qualified type name, but the declaration just uses the simple name. Markus