spec clarification: type annotations on static nested types
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 126.96.36.199 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 . The
> draft section on type_path mentions it distinguishes among locations
> where "an annotation may appear" , which as defined doesn't include
> qualifiers of static members.
> I see at least two options to reconcile the JVMS, javac, and core
> (a) Update JVMS 188.8.131.52 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 184.108.40.206 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
So, 220.127.116.11 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 18.104.22.168.
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.
More information about the compiler-dev