Invoking code generated by an annotation processor

Jonathan Gibbons jonathan.gibbons at oracle.com
Wed Feb 10 21:25:41 UTC 2016



On 02/10/2016 12:59 PM, Stéphane NICOLAS wrote:
> Thanks Jon for your fast answer. It's quite disappointing but it's 
> better to know it early.
> It's sad to see how much effort we have put in our annotation 
> processor, that it's a good idea but fails because of some general 
> java ecosystem issue.
>
> Though, talking of the issue with team mates, it became more clear. 
> Let me try to rephrase them more accurately than in my first mail.
>
> It seems to me that the design of javac could be improved to 
> accommodate these 2 scenarios :
>
>  1. in case of a parse error (for instance a missing ; a bad brace,
>     etc.) , javac should stop everything and report the actual
>     problem, without getting any further into the analysis and not
>     report any linkage problem (because javac would know that
>     annotation processors ain't gonna run and that can create false
>     positive about missing linkages. All other parse errors should be
>     reported.). It seems to me this would be a healthy "fail early"
>     design.
>

This is the intent.   Generally, javac is supposed to fail reasonably 
fast in general, and in that case in particular.     If you are seeing 
otherwise, please provide a test case, including the version of javac 
you are using.



>  1. in case of a linkage error (for instance having a non existing
>     import / calling a non existing method, etc.) then we should run
>     the annotation processors on the partial AST. This mechanism is
>     already in place to accomodate code generation.
>     Then the linkage problems should be resolved and take into account
>     the generated code, and only the remaining problems should show
>     up. This is where javac actually fails because it reports all
>     problems, including those that can be resolved by the code that is
>     actually generated. Javac reports problem from a previous internal
>     stage, it doesn't match the latest state it could reach internally
>     where only 1 problem could not be resolved, the one that was not
>     related to invoking generated code, it reports all linkages
>     problem exactly like if no code was generated and no annotation
>     processor had run.
>

That is the intent.

> Really, there is no way for javac to support those 2 scenarios ? I got 
> the strong feeling that it should but I understand my knowledge of 
> javac has huge holes. I have been surprised by the complexity of the 
> compiler's code.
>
> Thx again for your answer, it's been tremendously appreciated; there 
> are just a handful people would could have been able to answer my 
> question I am very happy someone actually did take the time to do it.
>
> Stephane
>
> 2016-02-10 11:41 GMT-08:00 Jonathan Gibbons 
> <jonathan.gibbons at oracle.com <mailto:jonathan.gibbons at oracle.com>>:
>
>
>
>     On 02/10/2016 09:09 AM, Stéphane NICOLAS wrote:
>>     I am facing a problem with Javac : I got a sweet annotation
>>     processor that generates a DSL and I invoke the generated code
>>     from my main code.
>>
>>     Everything works fine except when there is an error in my main
>>     code : if I got a compile error in the main code, not related to
>>     the generated code, like a missing comma (parsing problem), or
>>     calling an inexisting method (linkage problem), then all calls to
>>     the annotation processor are marked as errors by the compiler.
>>
>>     Ideally I am just looking for a way to get rid of those error
>>     messages, and keep only the original one that fails to compile.
>>
>>     AFAIK, javac should support this scenario but it doesn't support
>>     it in a very convenient way and I don't understand exactly why..
>>
>>     After reafing the javac code, open jdk 7 & 8, I realized that :
>>
>>     Annotation processors are not called if there is any error to
>>     compile the code. As the annotation processor are not triggered,
>>     the calls to generated code get mark as an error.
>>
>>     However, I could, by playing with shouldStopPolicy (+if error and
>>     if no error) trigger the annotation processor and generate the
>>     code. But still, I would receive in this case the errors related
>>     to calling the generated code. Like if the generated code was not
>>     taken into account, like if I was receiving errors from a
>>     previous compilation steps.
>>
>>     I understand that javac parses the code, if it fails there, I
>>     will receive only an error about the actual problem. And this is
>>     great. I just want this error to show up, not any other, and it
>>     works fine. (Though I am wondering if this is always true even I
>>     clean my build & generated files before compiling)
>>
>>     If there is a linkage problem in my original code, like calling
>>     an non-existent method, javac will relax the error and trigger
>>     the annotation processors and try to let them generate the code
>>     to see if the generated code that satisfies the linkage problem.
>>     But then, though there is a state in which javac will
>>     successfully satisfy all linkage related to generated code but
>>     not the other linkage error, I get all calls to generated code
>>     marked as errors. This is my problem. It looks like this internal
>>     state of the compiler is never accessible and errors returned do
>>     not match this state but more probably a previous internal state
>>     in which all linkage errors are aggregated and returned.
>>
>>     I think there is a solution to achieve what I want but I couldn't
>>     find one. And the situation is bad : it may actually cancel the
>>     development of the annotation processor lib I am developing. Just
>>     because the errors are flooding the actual problem in the code.
>>
>>     Would you have some time to advise me, and help me to make the
>>     lib work as expected.
>>     My goal is just to get only errors that are not related to
>>     calling generated code if they are not those who fail the
>>     compilation. I don't want to see my errors polluted by those
>>     calls if they are not responsible for breaking the compilation.
>>
>>     Stephane
>
>     Stephane,
>
>     In general, there is no convenient solution for you here, because
>     there is no way for javac to predict what unresolved symbols may
>     or may not be generated by the annotation processor that has yet
>     to be run.  And in general, it is not desirable to run annotation
>     processors if the input source code has significant errors, such
>     as syntax errors.
>
>     -- Jon
>
>

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


More information about the compiler-dev mailing list