[JSR308] Javac Processor API

Tom Ball Tom.Ball at Sun.COM
Fri Mar 2 11:00:57 EST 2007


Niko Matsakis wrote:
>> Your list of phases is incomplete.  Between parsing and annotation 
>> processing, the symbol (element) table is built.  That is easy to miss 
>> in the javac source, since the phase is internally called "enter".  
>> All class elements are created, along with member element initializers 
>> which get invoked on demand.  Since all symbols have types, those get 
>> created, too.  The model is "raw" at this point as there has been no 
>> type checks run yet, so basically you have a good model with 
>> compilable source code, but a flawed model if the source has 
>> attribution-level failures.
> 
> Yes, I left out the Enter pass for simplicity, but it is important and 
> so I should not have.  However, as I understand it, the Enter pass only 
> derives information for the "interface" of a class: i.e., the types of 
> its fields, method parameters, and the like.  It does not look inside of 
> a method, right?  Therefore, even if this pass has executed, attribute 
> processors still will not know (for example) whether "foo.bar" 
> represents a package, static field reference, etc.

I can understand trouble clearly understanding what is going on under 
the hood, as Javac's lazy initialization (called completion) is blurring 
the lines between its phases.  Yes, it's true that after Enter only 
class information has been calculated, but completers are all in place 
so that any request for type and element information is available on 
demand.  This includes type and element completers for all variables 
(including local), methods, parameters, and type parameters.  Completers 
may seem inefficient since they are all invoked in later phases, but 
they eliminate the need for cycle detection (asking for some type 
information may cause a cascade of completers to run, but they each only 
run once).  What is not available at this point is the type information 
on nodes which don't have elements such as expressions, which Attr creates.

Ignoring javac's implementation details, the requirement for entering 
the annotation processing phase is that all information needed to 
support the javax.lang.model.element and javax.lang.model.type APIs be 
available.  In javac's case most of the completers necessary to fully 
report all of this information won't have run yet, but they will be 
triggered on demand when the annotation processor is run.  If you are 
running annotation processors independent of compilation, this means 
potentially faster execution since only the type information the 
processor needs is calculated.  If run as part of compilation the main 
benefit is faster annotation processor error reporting.

Please note that just because JSR-305 defines annotations, it won't 
require that they can only be inspected by annotation processors. 
Annotations are just metadata, so a tool can either process the source 
code independently or inspect the class files (as FindBugs does).  New 
tools that need full attribution before analysis can do so easily with 
the javax.tools and Compiler APIs, running through the Attr phase using 
JavacTask.analyze().

> Anyhow, most likely this issue is out of scope for JSR308, but I wanted 
> to raise it in any case.

Sure; there is no point in designing something that can't be 
implemented, so raising general implementation questions like this is 
very appropriate.

Tom



More information about the JSR308 mailing list