Invoking code generated by an annotation processor

Jonathan Gibbons jonathan.gibbons at oracle.com
Thu Mar 3 16:24:07 UTC 2016


To pick up on this, briefly, to clarify,

> it's hard to say here if a source with those errors is syntactically 
> valid. 

No, it's not hard.  "Syntactically valid" simply means that javac can 
parse the source code and build a syntax tree. Informally, you can read 
this as saying, "can javac build a structural representation of the 
source code, such that it is reasonable to proceed with further 
analysis."   If javac can't even get to first base, then it will report 
errors and give up.

-- Jon



On 02/19/2016 07:50 PM, Stéphane NICOLAS wrote:
> Thx Joe for this historical precision, I appreciate it.
>
> I read carefully, and when the specs says :
>> If the source code is not syntactically well-formed or has some other 
>> irrecoverable error that could not be removed by the generation of 
>> new types, a model may or may not be provided as a quality of 
>> implementation issue.
> In the 2 cases we highlighted : a static import error or an erroneous 
> annotation value, it's hard to say here if a source with those errors 
> is syntactically valid.
>
> _If we consider it syntactically valid : _then those errors are not 
> recoverable, as they prevent the annotation processor from running. So 
> those errors should be reported. And javac does that. But it also 
> reports all cals to generated code as errors, which is our concern.
>
> Later, the specs says :
>> If a program is syntactically valid but erroneous in some other 
>> fashion, any returned model must have no less information than if all 
>> the method bodies in the program were replaced by "throw new 
>> RuntimeException();"
> Here, javac seems to fail in our case as the source code is 
> syntactically valid, but erroneous in some other fashion, but our 
> generated code is not assumed to have the form of empty classes, 
> methods etc.. The annotation processor is simply not run and those 
> errors are reported.
>
> So, if such errors are not considered syntax errors, javac doesn't 
> follow the specs.
>
> _If we consider the program is not syntactically valid : _then we fall 
> in a loophole of fuzzyness of the specs : a model may or may not be 
> provided as a quality of implementation issue. It looks like it's not 
> possible to generate a model that could be passed to annotation 
> processors because of those errors. Then only those should be reported.
>
> I tend to think there is something missing on this matter in the specs 
> you mention : an intermediary class of error.
>
> Unrecoverable errors :
>
>   * syntax errors are about the form of the program (missing commas,
>     braces, etc. name it). Those are reported well by javac, and only
>     them are reported. Perfect
>   * model building errors : static imports and annotation values
>     errors. Those are also reported well by javac but they drag along
>     with them error to generated code, the recoverable errors below.
>
> Recoverable errors :
>
>   * unknown classes or members of known classes : those are not
>     considered as error before annotation processing takes place.
>     Which is OK, but they are reported in case of model building
>     errors, which is our concern.
>
> So we can say here, to summarize the problem differently that right 
> after parsing a source and considering it valid, javac open a list of 
> errors it finds in the source. It adds all recoverable errors it finds 
> to save them for a next phase of processing after annotation 
> processing. But at that very precise moment, it also adds to the error 
> list the non recoverable model building errors. And if one is found, 
> then all errors are reported, which is not correct.
>
> The solution would be to separate model building errors and 
> recoverable errors right after having considered a program 
> syntactically valid.
> Maybe there is an intermediary phase needed to identify strictly non 
> recoverable model building errors and list them, before building the 
> model and detecting recoverable errors, which javac handles well.
>
> S.
>
>
> 2016-02-19 16:15 GMT-08:00 Joseph D. Darcy <joe.darcy at oracle.com 
> <mailto:joe.darcy at oracle.com>>:
>
>     Hello,
>
>     On 2/17/2016 11:00 AM, Jonathan Gibbons wrote:
>>     Stéphane,
>>
>>     Internally, during the period before anno processing, javac
>>     categorizes errors as recoverable or not, where "recoverable"
>>     means "could this error conceivably be fixed by running
>>     annotation processors, which may generate code."
>>
>>     It may be that we have to examine the scenario you describe to
>>     decide if the error should be marked as recoverable.
>>
>
>     To provide some additional historical context here, the first
>     generation annotation processing of apt in JDK 5 as well as the
>     standardized successor of javax.lang.model and
>     javax.annotation.processing in JDK 6 and later shared a
>     requirement of having to be able to process incomplete programs.
>     In particular, to allow processors to generated missing subclasses
>     and even superclasses of the the initial set of sources.
>
>     In general, it is impractical to describe exactly how a compiler
>     should model an incorrect program. The JSR 269 expert group took
>     some some pains to craft a specification would balance the need
>     for predictability while also allowing some room for
>     implementation-specific behavior: current version of this
>     specification with some refinements [1] over the years:
>
>>     During annotation processing, operating on incomplete or
>>     erroneous programs is necessary; however, there are fewer
>>     guarantees about the nature of the resulting model. If the source
>>     code is not syntactically well-formed or has some other
>>     irrecoverable error that could not be removed by the generation
>>     of new types, a model may or may not be provided as a quality of
>>     implementation issue. If a program is syntactically valid but
>>     erroneous in some other fashion, any returned model must have no
>>     less information than if all the method bodies in the program
>>     were replaced by "throw new RuntimeException();". If a program
>>     refers to a missing type XYZ, the returned model must contain no
>>     less information than if the declaration of type XYZ were assumed
>>     to be "class XYZ {}", "interface XYZ {}", "enum XYZ {}", or
>>     "@interface XYZ {}". If a program refers to a missing type
>>     XYZ<K1, ... ,Kn>, the returned model must contain no less
>>     information than if the declaration of XYZ were assumed to be
>>     "class XYZ<T1, ... ,Tn> {}" or "interface XYZ<T1, ... ,Tn> {}"
>     http://docs.oracle.com/javase/8/docs/api/javax/lang/model/element/package-summary.html
>
>     As Jon alluded to earlier in this thread, how javac implements
>     this aspect of the spec has evolved over time with the current
>     intention to forge ahead when generating a missing type could
>     allow the whole set of sources to compile successfully.
>
>     Cheers,
>
>     -Joe
>
>     [1] https://bugs.openjdk.java.net/browse/JDK-7003550
>
>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20160303/e216d2fe/attachment-0001.html>


More information about the compiler-dev mailing list