RFR: JDK-8198945: Invalid RuntimeVisibleTypeAnnotations for annotation on anonymous class type parameter

Werner Dietl wdietl at gmail.com
Sat Jul 7 02:24:17 UTC 2018


I agree that we should handle a NEW annotation on the anonymous class
creation like a NEW annotation on a method-local class instantiation.

In your example, the result should be equivalent to:

class Other {}
class Outer {
  class Inner {
    public void f() {
      class Local extends @A Other {};
      new @A Local();
    }
  }
}

That is, I would expect:

Outer$Inner.class for method f():
      RuntimeInvisibleTypeAnnotations:
        0: #19(): NEW, offset=0, location=[INNER_TYPE, INNER_TYPE]
          A

Outer\$Inner\$1Local.class for the class:
RuntimeInvisibleTypeAnnotations:
  0: #17(): CLASS_EXTENDS, type_index=65535
    A

As Alex points out, we shouldn't think of it as duplicating the @A
annotation in these two locations, but instead determine the correct
location for each individual use - as in the desugaring.

I therefore don't agree with the "ignoring" part in your last sentence
("This would involve creating INNER_TYPE entries corresponding to any
enclosing classes of the synthetic anonymous class declaration, and
ignoring INNER_TYPE entries on the supertype when propagating the
annotation.")

Take this slight re-shuffling of the example:

class Outer {
  class Other {}
  class Inner {
    public void f() {
      class Local extends @A Other {};
      new @A Local();
    }
  }
}

I would now expect:

Outer$Inner.class for method f():
      RuntimeInvisibleTypeAnnotations:
        0: #19(): NEW, offset=0, location=[INNER_TYPE, INNER_TYPE]
          A

Outer\$Inner\$1Local.class for the class:
RuntimeInvisibleTypeAnnotations:
  0: #18(): CLASS_EXTENDS, type_index=65535, location=[INNER_TYPE]
    A


The annotation location for the NEW would stay unchanged, but the
CLASS_EXTENDS now has an INNER_TYPE.

As an example where both NEW and CLASS_EXTENDS have the same number of
INNER_TYPEs:

class Outer {
  public void f() {
    class Local extends @A Other {};
    new @A Local();
  }
  class Other {}
}

In the following I would expect that the NEW has fewer INNER_TYPE than
the CLASS_EXTENDS:

class Outer {
  public void f(Inner i) {
    i.new @A Other() {};
  }
  class Inner {
    class Other {}
  }
}

but I didn't get the desugaring to work. (Is there a way to write the
desugaring?)

So instead of duplicating and filtering out some locations, we should
properly determine the locations for these two usages.

Does this sound good to you?

Best,
cu, WMD.

On Tue, Jul 3, 2018 at 6:17 PM Liam Miller-Cushon <cushon at google.com> wrote:
>
> On Tue, Jul 3, 2018 at 11:31 AM Werner Dietl <wdietl at gmail.com> wrote:
>>
>> 8198945/webrev.02 only creates the NEW annotation for @Foo(1), but not
>> for @Foo(3), because the latter has an INNER_TYPE location.
>> Maybe the right check is that old.position.location doesn't contain
>> any TYPE_ARGUMENT ?
>
>
> Good point. Do we also need to add an INNER_TYPE location to the NEW annotation, since the synthetic anonymous class declaration is itself an inner class? e.g. given:
>
> class Other {}
> class Outer {
>   class Inner {
>     public void f() {
>       new @A Other() {};
>     }
>   }
> }
>
> Do we need an [INNER_TYPE, INNER_TYPE] location to indicate that the NEW annotation is on the type Outer$Inner$1, not Outer or Outer$Inner?
>
> This would involve creating INNER_TYPE entries corresponding to any enclosing classes of the synthetic anonymous class declaration, and ignoring INNER_TYPE entries on the supertype when propagating the annotation.



-- 
http://www.google.com/profiles/wdietl


More information about the compiler-dev mailing list