Type annotations and this-reference (receiver) in methods

André Pankraz andre at pankraz.de
Sun Feb 16 12:13:51 PST 2014


Hi,

2 more possible issues I found:

1)
If you compile code without debug-info, then you don't have local variable
info with variable signatures, but you have the type annotations for local
variables in the bytecode.
The type pathes cannot really be applied without this info, especially for
type arguments etc., don't know how much sense it does make to include them
in this case?

2)
If you look into the following code, then I think the Method Reference Type
Annotations are missing the INNER path.
Focus onto first line testInnerGenericHandles().


public class DecTestMethodHandles {

    static class Test<S> extends DecTestMethodHandles {

        public static <T> void testStatic() {
            System.out.println("test");
        }

        public <T> Test() {
            System.out.println("new...");
        }

        public <T> void test() {
            System.out.println("test");
        }

        void testInnerGenericHandles() {
            Runnable r = @Nonnull Test<@Nonnull String>::<@Nonnull Integer>
new;
            r = @Nonnull Test::<@Nonnull Integer> testStatic;
            r = new @Nonnull Test<@Nonnull String>()::<@Nonnull Integer>
test;
            r = super::<@Nonnull String> testSimpleHandles;
        }
...
    }


You get this attribute in testInnerGenericHandles():

    RuntimeVisibleTypeAnnotations:
      #34 @org.decojer.cavaj.test.jdk8.Nonnull(
        target type = 0x45 CONSTRUCTOR_REFERENCE
        offset = 0
      )

There is no INNER path in this. According to the order how this is encoded
in bytecode, this bytecode presents "@Nonnull
DecTestMethodHandle.Test::new" and not
"DecTestMethodHandle. at NonnullTest::new" (or shorter "@Nonnull
Test::new")
Haven't tested it the type argument has same issues.

May be I understood the spec wrong here and here isn't a inner type path
necessary. It's the same topic like previous thread about INNER pathes.


It's just for your notice...really just some corner cases.


Best regards,
André






2014-02-10 21:05 GMT+01:00 André Pankraz <andre at pankraz.de>:

> Hi,
>
> just wanted to point out that the Type Annotation Path for "Outer<W>.Inner
> this" cannot be be a class reading tool, because the necessary information
> is missing in the class (or you parse all enclosing classes before and try
> to build the full type from the constraints about "this"). This might not
> be that interesting for the compiler, but might be a real problem for tools
> that target the type information, like the type checker.
>
> Personally I don't have a problem with this - I don't care and just
> stumbled over this, just wanted to mention that there is either a missing
> restriction about "this" (cannot annotate enclosing type arguments here) or
> a missing info in the bytecode or I understood it wrong.
>
>
> And because you mention it...yes I assume this whole approach with type
> annotations in seperate attributes which contain all these different type
> pathes, thats an architecture decission that comes with a lot of technical
> burden.
> May be it would have been better to restrict the expressiveness of type
> annotations (this here doesn't look like Javas usual 80/20 rule, more like
> 120...) and to extend the signature language to embed this info and to
> provide a method to apply signature info to operations with type info/stack
> frames. But maybe I just cannot see the problems here. But as you
> sait...all moot :)
>
> Cheers,
> André
>
>
> 2014-02-10 20:42 GMT+01:00 Alex Buckley <alex.buckley at oracle.com>:
>
> Andre,
>>
>> While the Signature attribute mechanism can represent parameterized types
>> and type variables in a class file, it is not appropriate for testInnerNew.
>> A Signature attribute is meant to record a method's Java type signature,
>> which officially does not include a formal parameter representing 'this'.
>> The formal parameter representing 'this' appears in the descriptor of
>> testInnerNew, as you noted, but the point of the Signature attribute is to
>> give Java-level types, not bytecode-level types.
>>
>> That said, this is really all moot, since the broader problem is that it
>> is not possible to record the signatures of annotated parameterized types
>> where they appear in a method body, e.g. in a qualified class instance
>> creation expression of a parameterized type. JSR 308 didn't attempt to
>> solve this problem.
>>
>> Alex
>>
>>
>> On 2/8/2014 11:29 AM, André Pankraz wrote:
>>
>>> Hi,
>>>
>>> thx so far for the other answers, next remark ;)
>>>
>>>
>>> Regard the following (artificial) code example.
>>> Just focus onto the first parameter in "testInnerNew(Inner this)", don't
>>> had time to create a minimalistic example, just want to explain my issue:
>>>
>>> ------
>>>      class Outer<W> {
>>>
>>>          class Middle {
>>>
>>>              class Inner extends
>>>                      Outer<@Size(max = 21) String>. at Size(max = 22)
>>> Middle {
>>>
>>>                  @Nonnull
>>>                  Inner testInnerNew(
>>>                          Outer<@Size(max = 24) W /* <W> is necessary!
>>> */>. at Nonnull @Size(max = 25) Middle. at Size(max = 26) Inner this,
>>>                          @Size(max = 27) Integer arg) {
>>>                      // Eclipse Bug?: Outer<String> not allowed
>>>                      return new Outer. at Size(max = 28) Middle. at Size(max =
>>> 29) Inner(
>>>                              arg);
>>>                  }
>>>
>>>              }
>>>
>>> ----
>>>
>>> In my eyes we have a problem here with the missing signature of the
>>> first parameter on the method testInnerNew(), which isn't a real
>>> argument in bytecode but is just syntactix sugar in Java to add type
>>> annotations to the receiver type for the method callout.
>>>
>>> Now with the choosen architecture to store type annotations in seperate
>>> attributes and add all this type path stuff to it, you now are heavily
>>> dependent on matching descriptors, signatures and inner/outer type
>>> information - or you cannot apply the type path properly. (I still don't
>>> understand this architecture, but different topic...)
>>>
>>>
>>> If I want to apply the @Size(max = 24) at the given position I need the
>>> full signature of this parameter, inclusing parameterized types with
>>> type variable W.
>>> It isn't in the bytecode (and cannot be, is not a real parameter there).
>>>
>>> So you could suggest to just create the signature of the given
>>> information, because the first artificial "this" parameter has the
>>> constraint to be exactly the same like the enclosing types. This means I
>>> have to:
>>> * go through all enclosing types (need all inner/outer type info and
>>> descriptors here)
>>> * for all enclosing types that have type parameters, I create a
>>> parameterized type with type variables, that match the type parameter
>>> names
>>> * create a fully qualified type from this
>>>
>>> Yes...I tried it, but then I noticed, that now you are dependent from
>>> the fact, that all enclosing classes are already parsed first, or you
>>> cannot get their type parameters.
>>> Till now each class has all relevant info by itself (e.g. all
>>> inner/outer info for all referenced classes) - now this would change.
>>> So I could reorder my classes...on the other side not that easy if you
>>> directly read JARs / later Pack2000 on the fly to build a full type
>>> model.
>>>
>>> Is this intentional? Or is there a mistake in my remarks?
>>>
>>>
>>> Cheers,
>>> André
>>>
>>>
>>>
>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/type-annotations-dev/attachments/20140216/0db55e60/attachment.html 


More information about the type-annotations-dev mailing list