<div dir="ltr">Hi Alex,<br><div><br></div><div>Thanks for digging up those threads, I hadn't seen the earlier discussions.</div><div><br></div><div>I do not have a strong opinion about the decision to emit annotations on anonymous class supertypes as both CLASS_EXTENDS and NEW, vs. just CLASS_EXTENDS. Unless others on this thread are interested in revisiting it, I'm now leaning towards keeping the current approach.</div><div><br></div><div>Here's the updated webrev to do that: <a href="http://cr.openjdk.java.net/~cushon/8198945/webrev.01/index.html" target="_blank">http://cr.openjdk.java.net/~cushon/8198945/webrev.01/index.html</a></div><div><br></div><div>The patch to Annotate is still necessary to prevent annotations like @TB from being attached to the enclosing method (rather than the code attribute). The revised patch to TypeAnnotations keeps the copyNewClassAnnotationsToOwner helper that propagates annotations on anonymous classes to the 'new' expression, but fixes it to preserve the relative position information of annotations that are not on the top-level type.</div><div><br></div><div>Here's a demo. Note that the 'NEW' annotations are identical for both the anonymous and named new expressions:</div><div><br></div><div>```</div><div><div>import java.lang.annotation.*;</div><div><br></div><div>class Test {</div><div>  @Target(ElementType.TYPE_USE) @interface TA {}</div><div>  @Target(ElementType.TYPE_USE) @interface TB {}</div><div><br></div><div>  interface I<T> {}</div><div>  static class J<T> {}</div><div><br></div><div>  void f() {</div><div>    new @TA I<@TB Object>() {};</div><div>    new @TA J<@TB Object>();</div><div>  }</div><div>}</div></div><div>```</div><div><br></div><div>$ javap -v -p Test<br></div><div><div>  void f();</div><div>...</div><div>      RuntimeInvisibleTypeAnnotations:</div><div>        0: #22(): NEW, offset=9</div><div>          Test$TA</div><div>        1: #23(): NEW, offset=9, location=[TYPE_ARGUMENT(0)]</div><div>          Test$TB</div><div>        2: #23(): NEW, offset=0, location=[TYPE_ARGUMENT(0)]</div><div>          Test$TB</div><div>        3: #22(): NEW, offset=0</div><div>          Test$TA</div></div><div><br></div><div>$ javap -v -p 'Test$1'</div><div>...</div><div><div>RuntimeInvisibleTypeAnnotations:</div><div>  0: #21(): CLASS_EXTENDS, type_index=0, location=[TYPE_ARGUMENT(0)]</div><div>    Test$TB</div><div>  1: #24(): CLASS_EXTENDS, type_index=0</div><div>    Test$TA</div></div><div><br></div><div></div></div><br><div class="gmail_quote"><div dir="ltr">On Fri, Jun 29, 2018 at 4:39 PM Alex Buckley <<a href="mailto:alex.buckley@oracle.com" target="_blank">alex.buckley@oracle.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On 6/29/2018 3:55 PM, Liam Miller-Cushon wrote:<br>
> The handling of @TB in particular is clearly incorrect:<br>
><br>
> * @TB appears with a `NEW` type path that leads to the top-level type of<br>
> the 'new' expression, even though @TB appeared on a type argument of<br>
> that type and not at the top level.<br>
><br>
> * @TB also appears on 'f' with a `CLASS_EXTENDS` path and no bytecode<br>
> offset, which does not provide enough information to associate it with<br>
> the annotated location.<br>
<br>
I agree with both points. It is egregious that the method_info structure <br>
for `f` (as opposed to the Code attribute therein) as a <br>
Runtime*TypeAnnotations attribute.<br>
<br>
> The handling of @TA is also questionable. It makes some sense to use the<br>
> same type path for an annotation on the type of an anonymous class<br>
> declaration as the type of a regular 'new' expression. However that<br>
> results in the same use of @TA appearing twice in bytecode, and<br>
> conflates the type of the anonymous class with its supertype.<br>
><br>
> I think it is more correct to only emit @TA as a `CLASS_EXTENDS`<br>
> annotation on Test$1, and not include a copy of it at the enclosing method.<br>
<br>
I did some digging and found three threads from 2013:<br>
<br>
1. "Annotations on anonymous classes"<br>
<a href="http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-February/000063.html" rel="noreferrer" target="_blank">http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-February/000063.html</a><br>
<br>
2. "Desugaring of anonymous classes"<br>
<a href="http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-April/000092.html" rel="noreferrer" target="_blank">http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-April/000092.html</a><br>
<br>
3. "Desugaring of anonymous classes" (followup)<br>
<a href="http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-August/000127.html" rel="noreferrer" target="_blank">http://mail.openjdk.java.net/pipermail/type-annotations-spec-experts/2013-August/000127.html</a><br>
<br>
It seems like I changed my mind on the matter of recording @TA:<br>
<br>
- In February I agreed with your view, Liam, that @TA should appear only <br>
as a CLASS_EXTENDS path in the implicit class declaration (Test$1), and <br>
not as a NEW path in the code of `f`.<br>
<br>
- But in April, I said that @TA should be recorded as both paths. Per <br>
the followup mail in August, this was driven by a longstanding policy <br>
that "In the classfile, the type annotations are copied to the class <br>
declaration and to its instantiation (new expression)."<br>
<br>
In June 2018, I do not mind whether @TA appears as CLASS_EXTENDS only, <br>
or as CLASS_EXTENDS + NEW. If you and Werner have agreed on <br>
CLASS_EXTENDS only, and if your fix (which is mostly deletion) makes the <br>
recording of both @TA and @TB more reliable, then I defer to your decision.<br>
<br>
Alex<br>
</blockquote></div>