spec clarification: type annotations on static nested types

Alex Buckley alex.buckley at oracle.com
Tue Nov 20 20:06:43 UTC 2018


// Please disregard my prior mail as it had a typo for the option.

On 11/19/2018 6:21 PM, Liam Miller-Cushon wrote:
>  From some offline discussion with Mike and Werner, the original intent
> was for "nested type" in JVMS 4.7.20.2 to only apply to non-static members.
>
> I couldn't find related discussions in type-annotations-spec-experts.
> However there's some language in the jsr308 draft about locations where
> type annotations may appear, which mentions 'scoping mechanisms' and
> which rules out annotations on qualifiers of static members [1]. The
> draft section on type_path mentions it distinguishes among locations
> where "an annotation may appear" [2], which as defined doesn't include
> qualifiers of static members.
>
> I see at least two options to reconcile the JVMS, javac, and core
> reflection.
>
> (a) Update JVMS 4.7.20.2 to mention non-static members, update core
> reflection to match, and leave javac's current behaviour as-is.
> (b) Change javac's behaviour to emit type path entries for both static
> and non-static member classes.
>
> I think there are a couple of reasons to prefer (a).
> * It results in slightly more efficient class files, with more compact
> type_path structures.
> * it avoids breaking compatibility with the code javac and ecj have been
> generating since JDK 8. Changing getAnnotatedOwnerType seems lower-risk
> since it was added more recently, and (due to the issue we're
> discussing) doesn't work reliably.

Thanks for investigating. Now that the original intent is clear, we 
could adopt option (a). That involves thinking about how to narrate the 
change in the JVMS -- we need more color than simply adding "non-static" 
to a sentence in 4.7.20.2 and moving on.

It appears the original intent was to have the class file structure 
follow the Java language constructs precisely, rather than to let the 
class file express more than the language (say, by tracking annotations 
on uses of static nested types). This intent is unusual in the broader 
picture, where class files are often more expressive than language 
constructs, but it's in line with how type_path is already able to 
express annotations on language-only constructs such as wildcards.

"Scoping mechanism" is an informal concept that is not present in the 
JLS. It was formalized into the concept of "type contexts" in the Public 
Review of JSR 308. (For the details, read chapter 1 of the spec in that 
Public Review -- 
https://jcp.org/aboutJava/communityprocess/pr/jsr308/index.html -- to 
see how the oft-quoted declarative spec in java-annotation-design.html 
turned into a precise operational spec.) In addition, the ability to 
write `@Foo A.B` or `A. at Foo B` or neither was defined in terms of the 
qualified-this construct -- see JLS 9.7.4 and the definition of 
"admissible" 
(https://docs.oracle.com/javase/specs/jls/se11/html/jls-9.html#jls-9.7.4-400).

So, 4.7.20.2 should seek to capture the original intent by describing 
how type_path in the class file matches up with "admissible" annotations 
on type uses with qualified names. I see that JDK-8198526 describes the 
problem (though with a critical typo in the second code sample) -- 
please file a corresponding specification/vm bug that:

1. Explains the problem using the JLS concepts I mentioned above (rather 
than appealing to an undefined "annotatable type" concept).
2. Proposes normative text for 4.7.20.2.
3. Expands the existing Outer.Middle.Inner example to say when @Foo 
could appear on each name (because it counts as admissible) and thus 
what the type_path would be.

Alex


More information about the compiler-dev mailing list