Some thoughts on javax.lang.model support for preview language features

joe darcy joe.darcy at
Thu Mar 22 05:23:49 UTC 2018

Hi Maurizio,

As a historical note, in times past javac did not have a 1:1 mapping 
between public -target alternatives and values in the Target 
enumeration; there were some synthetic values we've since removed 
(JDK-8010179: Remove transitional target values from javac). However, I 
agree it is preferable to not introduce such complications into the 
Source enum unless necessary.

If a PREVIEW constant were to be added, I think it would be reasonable 
to define latest and latestSupported to *not* return PREVIEW.

Are are some dual method pairs in javax.annotation.Processor and 
javax.annotation.ProcessingEnvironment including 
getSupportedSourceVersion and getSourceVersion.

If the preview-ness is not conveyed view a new SourceVersion enum, then 
I'd recommend:

      default isPreviewSupported() { return false; }

as you've suggested and a similar default method on ProcessingEnvironment.

(Further support could involved an update to AbstractProcessor to parse 
a PreviewSupported annotation, etc., but I don't think the duty cycle 
would be high enough to need this.)



On 3/16/2018 6:02 AM, Maurizio Cimadamore wrote:
> Hi Joe,
> I did some experiments along those lines few weeks ago and concluded 
> that, while the idea of having a separate source version for PREVIEW 
> is attractive, it is not as straightforward as it seems. Here is some 
> evidence:
> * in javac, there's a 1-1 mapping between javac's Source enum 
> constants and SourceVersion enum constants, which means if we have 
> SourceVersion.PREVIEW, we probably should have Source.PREVIEW too
> * pulling more on that string, in javac there's a 1-1 mapping between 
> the source levels available in the Source enum and the values that can 
> be passed to the -source flag. But, if we add Source.PREVIEW, this 
> would break that invariant, and we would now have a source version 
> that is 'non denotable' via command line options. This distinction 
> seems to have deep implications both in javac and in tests.
> * diagnostics; the set of diagnostics given for preview features when 
> they are not enabled is almost certainly distinct from those given 
> when you e.g. try to use lambdas with -source 7.
> * more onto the point - SourceVesrion has a couple of static methods:
> public static SourceVersion latest()
> private static SourceVersion getLatestSupported()
> What should these method return? 11 or PREVIEW? Also, note that the 
> last method is affected by the value of the runtime property 
> "java.specification.version", so any change here require some synergy 
> with the runtime.
> All this left a sour taste on my mouth; having PREVIEW to mean 
> Source.N + 1 seems appealing, but at the same time very problematic; 
> if we instead treat preview has an orthogonal toggle, a lot of the 
> complexity just disappears. I'm not sure what an equivalent of that 
> toggle might be in the JLM-land - probably another way to get there 
> would be to add a default method to the Processor interface - e.g.
> default isPreviewSupported() { return false; }
> And then augment the SupportedSourceVersion annotation:
> public @interface SupportedSourceVersion {
>     SourceVersion value();
>     boolean preview default false;
> }
> Thoughts?
> Maurizio
> On 16/03/18 04:45, Joseph D. Darcy wrote:
>> Hello,
>> As you may have seen elsewhere, JEP 12: Preview Language and VM 
>> Features ( is proposing to include 
>> preview language features as part of the platform. The JEP has been 
>> discussed in various threads on jdk-dev ([1], [2], etc.) Since one of 
>> the various and sundry aspects of supporting a language is updating 
>> the language model API [3], it is worthwhile to discuss a few 
>> alternatives in terms of how the language model API could support 
>> preview features
>> The javax.lang.model APIs are part of the Java SE API and thus live 
>> by the strict compatibility rules of that space, with some slight 
>> accommodations for certain technical aspects of the API.
>> For the sake of argument, let's assume we do *not* want to change 
>> mainline javax.lang.model API to describe the preview features. The 
>> ElementKind.OTHER and TypeKind.OTHER values are meant to indicate an 
>> object is outside of the values for the standardized system. Subtypes 
>> of the modeling interfaces and visitors can then be used as needed 
>> for the specialized and extended system. (Joel Borggren-Franck and I 
>> used this approach in the javax.lang.model backed by core reflection 
>> prototype from a few years back, JEP 119: javax.lang.model 
>> Implementation Backed by Core Reflection.)
>> However, using such an extended API inside javac (or in annotation 
>> processors) is tedious.
>> One could imagine a system where a different, updated, version of 
>> javax.lang.model were used when the incubating features were unlocked 
>> via upgrading its module or the like, but that would be awkward as well.
>> If our intention is to only support one preview version at a time, 
>> part of the API approach could be to add a "PREVIEW" constant to 
>> SourceVersion that was always the most latest version. In other words 
>> in JDK 11 we'd have
>>     RELEASE_0,
>>     ...
>>     RELEASE_11,
>>     PREVIEW;
>> and in JDK 12
>>     RELEASE_0,
>>     ...
>>     RELEASE_11,
>>     RELEASE_12,
>>     PREVIEW;
>> Processors could them indicate they support the "PREVIEW" release value.
>> The longer-term javax.lang.model API evolution to-do list includes 
>> thinking about other ways to evolve the visitors to support new 
>> language features. We've stopped automatically adding new visitors 
>> with every release, now only adding them as needed and we didn't need 
>> a new batch for 10. We could potentially have a similar structure for 
>> visitors with a cadre of "Preview" visitors as the most specialized 
>> versions in a release and new per-release visitors getting introduced 
>> as superclasses afterward.
>> The main risk is pulling or changing the incubating feature in some 
>> way that would be incompatible with the API support added for it.
>> Recent discussions have suggested @Deprecating new API items added to 
>> support preview features. Can is a reasonable precaution to 
>> discourage accidental dependence on them, but at times the behavior 
>> of existing methods is also changes so deprecation would not be a 
>> good fit.
>> Cheers,
>> -Joe
>> [1] 
>> [2] 
>> [3] 

More information about the compiler-dev mailing list