Invoking code generated by an annotation processor
Stéphane NICOLAS
steff.nicolas at gmail.com
Thu Mar 3 15:48:46 UTC 2016
Thx a lot Jon, it's perfect like this. We wil soon pass to java 9 in our
android development anyway.
If you could link the issue here once you create it, so that we can follow
it up, that would be great.
S.
2016-03-03 7:37 GMT-08:00 Jonathan Gibbons <jonathan.gibbons at oracle.com>:
> Stephane,
>
> I will create an issue to track this. I cannot make promises about fixing
> this, but if we do, it would be fixed in 9 first, and then maybe backported
> to 8.
>
> -- Jon
>
>
>
> On 03/02/2016 06:48 PM, Stéphane NICOLAS wrote:
>
> @jonathan, is there any chance this will get fixed in a future release of
> javac ? (7 &/or 8+, we actually don't really mind about java 7 on our
> side).
>
> Thx in advance,
> Stephane
>
> 2016-02-19 19:50 GMT-08:00 Stéphane NICOLAS <steff.nicolas at gmail.com>:
>
>> 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>:
>>
>>> 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/9edf5c7b/attachment.html>
More information about the compiler-dev
mailing list