Invoking code generated by an annotation processor
Jonathan Gibbons
jonathan.gibbons at oracle.com
Thu Feb 11 19:03:23 UTC 2016
Stéphane,
Can you reduce the test case down to a simple one(s) that you can post here?
-- Jon
On 02/11/2016 10:44 AM, Stéphane NICOLAS wrote:
> Hey Jon,
>
> we are going to create an example based on our annotation processor.
> It will come in the form of a github repo, 1 branch that compiles
> fine, 2 branches to illustrate different compile problems. Everything
> is mavenized so it should work out of the box for you. We will also
> tell you what error messages we have on the 2 failing branches, actual
> and expected behavior, and provide you with our javac version(s).
>
> We hope this can help, thank you very much for your answers.
>
> Stéphane
>
>
> 2016-02-10 13:25 GMT-08:00 Jonathan Gibbons
> <jonathan.gibbons at oracle.com <mailto:jonathan.gibbons at oracle.com>>:
>
>
>
> 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/20160211/aa8a9153/attachment.html>
More information about the compiler-dev
mailing list