[Checkers] Compiler annotations output

Michael Ernst mernst at csail.mit.edu
Wed Jul 2 08:04:06 EDT 2008


Mahmood-

> All annotations now appear in the class file.

Fantastic!  That's great news.  It will be easier to fix things now that
they are all there.

> Currently, I don't think those values get set properly.  For the  
> following declaration for example:
> 
> @interface A {}
> @interface B {}
> 
> class Test extends @A Date implements @B RandomAccess { }
> 
> Both annotations get written to the classfile, however their pos and  
> offsets are the same.  The compiler outputs the following debugging  
> output:
> writing @A at [CLASS_EXTENDS @-1 offset -1]
> writing @B at [CLASS_EXTENDS @-1 offset -1]
> 
> I cannot see how to differentiate between them.

Do you mean that you don't how the classfile format should differentiate
them, or that  you don't understand how the compiler can tell the
difference between them from the AST?  I suspect it's the former.

See section 4.1 at
http://groups.csail.mit.edu/pag/jsr308/specification/java-annotation-design.html#htoc8

Compared to annotation, the extended_annotation structure contains two
additional fields.  These fields implement a discriminated (tagged) union
type:  field target_type is the tag, and its value determines the size and
contents of reference_info (which sometimes has zero size).

If the annotation target is one of these two values:

  class extends/implements	0x14
  class extends/implements generic/array	0x15

then section "Class extends and implements Clauses" later in the document
says:

  type_index specifies the index of the type in the clause:  -1 (255) is
  used if the annotation is on the superclass type, and the value i is used
  if the annotation is on the ith superinterface type.

Now, there is a problem here in that we don't know if i counts from 0 or 1
(that should be fixed).  But I would say that @B should have a "type_index"
field of 0, whereas @A should have a "type_index" field of -1.

> Processing annotations is (more used  
> to before my change) divided between the following:
> - Parser: parsing the annotations
> - Attr: In the attribution phase, attributing the annotation trees.  
> i.e. enriching the annotation trees with their symbol and type  
> information.
> - Desugering (TransType): Calculates the position for each annotation
> - Code Generation (Gen): Lifts the type annotations to the most  
> enclosing symbol: field, method, or class tree; as annotations would  
> be attached to those symbols in the classfile. -- I moved this  
> functionality to desugering stage
> - ClassWriter: writes the annotations to the classfile.

Wow.  Could you document this?  In our repository (as opposed to a public
document) is OK.  You could use $anno/README.txt or some other place that
you choose.

> The problem was that in the desugering stage, the compiler rewrites  
> tree and trim some parts of it, namely:
> - annotations on the extends and implements clauses
> - all type arguments for parameterized types

Why does it do that?  Because it knows that the old-style annotation
processors can't possibly need them?  For some other reason?  Is the
solution to change the compiler to not remove those annotations?

                     Thanks,

                    -Mike



More information about the checkers mailing list