spec clarification: type annotations on static nested types

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


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 indeed adopt option (2). 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 describe 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