type_path of constructors for inner classes
Alex Buckley
alex.buckley at oracle.com
Mon Oct 14 12:41:14 PDT 2013
Hi Werner,
On 10/11/2013 10:00 PM, Werner Dietl wrote:
> On 10/11/2013 10:56 PM, Alex Buckley wrote:
>> On 10/11/2013 5:13 PM, Werner Dietl wrote:
>>> Are you saying the correct annotations for the constructor of Inner
>>> would be:
>>>
>>> RuntimeVisibleTypeAnnotations:
>>> 0: #16(#17=I#19): METHOD_RETURN
>>> 1: #16(#17=I#18): METHOD_RETURN, location=[INNER_TYPE]
>>> 2: #16(#17=I#19): METHOD_RECEIVER
>>>
>>> That is, the @Annot(1) from the receiver appears again on the return
>>> and the @Annot(0) appears on the return, with a location.
>>> Or should we avoid this duplication and only keep 1 and 2, that is the
>>> two explicit annotations?
>>
>> Given:
>>
>> @Annot(0) Inner(@Annot(1) Test Test.this) {}
>>
>> I think the most natural thing to do is emit 0 and 1 and 2. Everywhere a
>> simple name of a nested type occurs, javac "expands" the simple name to
>> a qualified name when emitting class files. It seems perfectly
>> consistent to "expand" the zero-length string representing the type of
>> the newly constructed object into the qualified name "Test.Inner" - the
>> "Inner" which appears before the left paren is a simple type name for
>> sure, but the type of the constructed object is more than that.
>>
>> Then, we can determine what annotations appear on the "Test" and what on
>> the "Inner" in the type "Test.Inner" :
>>
>> - The "Test" in the type of the newly constructed object is a different
>> entity than the "Test" in the type of the receiver parameter, but it's
>> reasonable to copy @Annot(1) from the latter to the former.
>>
>> - The "Inner" in the type of the newly constructed object is then
>> obviously annotated one level down with @Annot(0).
>>
>> I can add language to the JLS to state that the type of the newly
>> constructed object, if annotated, is the fully qualified name of the
>> type; and that any annotations on the receiver type's parameter apply to
>> the appropriate simple type name within the fully qualified name.
>
> From the javac side, I think I can implement this.
> However, what should happen if the bytecode contains:
>
>>> RuntimeVisibleTypeAnnotations:
>>> 0: #16(#17=I#666): METHOD_RETURN
>>> 1: #16(#17=I#18): METHOD_RETURN, location=[INNER_TYPE]
>>> 2: #16(#17=I#19): METHOD_RECEIVER
>
> That is, the return type and receiver type annotations for "Test" are
> different?
> Will this be a verification error? Will the language model or reflection
> expose those different annotations? Is this simply the bytecode being
> more expressive and the Java language model ignores it?
> Not having this duplication of information would probably be simpler to
> specify.
After some more thought, I agree with you. Let's leave the receiver
parameter out of this entirely. The type of the newly constructed object
has a fully qualified name, but only the final simple name in the
qualified name has the annotation from the left of the ctor declaration.
That's consistent with the attribute emitted for "Test. at Foo Inner"
anywhere else in the body of Inner.
As an aside, the conceptual step called "verification" does not inspect
Runtime*Annotation attributes; the content of such attributes is a
matter for reflection APIs. (I'm wording that sentence carefully because
verifier implementations sometimes perform load-time activities like
checking constant pool typing; but conceptually that's not part of
verification.)
> What is the JLS name for the type in a "new" expression - which I would
> colloquially call the type of a newly constructed object?
"The type in a class instance creation expression". Given a class
instance creation expression, it's not immediately and trivially obvious
which constructor will be run. You'll only have a newly constructed
object after one has been run, so a TYPE_USE annotation preceding a ctor
declaration is much "closer" to the "type of the newly constructed
object" than the CICE which utters a type name.
Alex
More information about the type-annotations-dev
mailing list