Improving compiler messages for preview API

Maurizio Cimadamore maurizio.cimadamore at
Fri Aug 9 00:08:59 UTC 2019

Late to the party

There is a tension between having an annotation - and then claim that 
said annotation can only be used in A, B, C.

Another possible path would be to explicitly list in the compiler the 
set of preview method symbols - I'm pretty sure this can be made to work 
reliably - but it kind of miss a big point: an annotation is not just 
there for telling javac what to do (which we can do in other ways), it's 
also there as a source of _documentation_ - both for the source and, 
more importantly, Javadoc.

Ideally, what you want is to add @Preview in a non-exported package, 
(pretty much as @ForceInline) so that it can be used wherever (including 
non SE APIs) in the JDK (provided the package is qualified-exported 
accordingly) - and that takes care of the fact that the annotation could 
not be placed on code outside of the JDK.

The big problem of this approach is that, of course, it would be a bit 
odd to define what the behavior of the preview feature should be, 
especially, what the compiler should do when encountering a method 
marked with @Preview, if @Preview itself is not part of the Java SE API 
- meaning a spec (e.g. JLS) cant really refer to it. But, is there a 
need for the spec to refer to it? Could we get away with saying that 
"there must be a way to mark preview API methods" without saying _what_ 
way that is?


On 07/08/2019 21:22, Alex Buckley wrote:
> On 8/7/2019 11:52 AM, Joe Darcy wrote:
>> To be precise on terminology, if compiling with --enable-preview, I 
>> think the warnings generated for using preview languages feature and 
>> associated API elements should be a little-w warnings. That is, 
>> messages from the compiler that still allows the compile to exist 
>> with a zero exit code. Operationally, such messages would be 
>> Diagnostic.Kind.NOTE rather than Diagnostic.Kind.{WARNING, 
> Sure, that is a decision for javac.
>>> 3. At run time -- If you compile without --enable-preview, and the 
>>> source code refers to an API element associated with a preview 
>>> feature, then javac could give a (non-suppressible) warning and 
>>> _mark the class file as depending on preview features_. It is 
>>> important to handle this scenario firmly because the API element 
>>> might be gone in a later release. Annotating the type/method gives 
>>> grounds for javac to explain what's going on: "This method is marked 
>>> @Preview; your class file is now preview-feature dependent."
>> As I understand it, currently the call file target to use in javac is 
>> determined solely from the command line arguments at the start of the 
>> compile. It may be awkward to change this during the compile. (And 
>> would it change only for the for the types using the preview feature 
>> or fall all types in the compile?)
> Does "call file target" mean "class file target", e.g. 57.0 versus 
> 57.65535? I suspect it's moot anyway -- this thread has already moved 
> on from "give a warning, and mark the class file as depending on 
> preview features", to "give an error, so no class file to worry about."
>>> The annotation type that you defined in the webrev 
>>> (j.l.a.PreviewFeature) looks good. However, I don't think the 
>>> `release` element is needed. The API in SE $N is what it is; API 
>>> elements associated with a preview feature are there because a JEP 
>>> put them there. The `release` element would always be the current 
>>> JDK release.
>> It isn't necessarily the case an API associated with a preview 
>> feature will have been introduced in the most recent JDK. For 
>> example, treating JEP 325: "Switch Expressions (Preview)" in 12 and 
>> JEP 354: "Switch Expressions (Preview)" in 13 as iterations of the 
>> same feature, the tree API has methods to support switch expression 
>> support from both JDK 12 and 13:
>> SwitchExpressionTree introduced in 12, still in use in 13:
>> YieldTree introduced in 13:
>> >
>> This situation hasn't occurred yet in the Java SE APIs, but if the 
>> iterations of a feature are previewed over multiple releases, it 
>> certainly could.
>> The "release" element was modeled after the "since" element in 
>> java.lang.Deprecated. It isn't essential information, but I think it 
>> is useful to have it presented.
> Sorry, I am not concerned with how to mark compiler-internal APIs that 
> support preview features, whether in javac or in any other compiler. 
> The audience of developers who might accidentally over-rely on such 
> APIs is tiny. I am concerned about how to mark Java SE APIs as being 
> associated with preview features, because the audience of developers 
> who might accidentally over-rely on them is enormous. In that vein, if 
> an SE 12 preview feature re-previews in SE 13, then any associated API 
> in 13 should NOT say @PreviewFeature(release="12") -- even if the API 
> is unchanged between 12's preview feature and 13's preview feature. 
> The JEP which does the re-previewing is responsible for saying how 
> associated APIs from the first round evolve in the second round, so by 
> definition, any associated API present in 13 is the 13 version, and 
> `release="13"` is unnecessary.
> Alex

More information about the compiler-dev mailing list