Bug 50443 - [1.5][dom] DOM support for JSR-175 metadata
Summary: [1.5][dom] DOM support for JSR-175 metadata
Status: RESOLVED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.0   Edit
Hardware: All All
: P3 enhancement (vote)
Target Milestone: 3.1 M1   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2004-01-22 19:16 EST by Jim des Rivieres CLA
Modified: 2005-01-11 11:01 EST (History)
4 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jim des Rivieres CLA 2004-01-22 19:16:56 EST
JSR-175 (metadata) is a candidate for inclusion in J2SE 1.5.  We should 
tentatively add support for metadata in DOM/AST.
Comment 1 Jim des Rivieres CLA 2004-01-22 19:26:41 EST
Here is a sketch of the changes required to DOM/AST for JSR-175 Metadata 
("annotations"). I'll assume here that the changes for JSR-014 ("generics") 
and JSR-201 ("enums", "foreach", etc.) are already included.

==========================================
New grammar rules:

Annotation:
  NormalAnnotation
  MarkerAnnotation
  SingleMemberAnnotation

NormalAnnotation:
  <b>@</b> Name <b>(</b> [ MemberValuePair { <b>,</b> MemberValuePair } ] <b>)
</b>

MemberValuePair:
  SimpleName <b>=</b> Expression

MarkerAnnotation:
  <b>@</b> TypeName

SingleMemberAnnotation:
  <b>@</b> TypeName <b>(</b> Expression  <b>)</b>


AnnotationTypeDeclaration:
     [ Javadoc ] { Modifier | Annotation } <b>@</b> <b>interface</b> Identifier
		<b>{</b> { AnotationTypeMemberDeclaration | <b>;</b> } <b>}</b>


AnotationTypeMemberDeclaration:
   [ Javadoc ] { Modifier | Annotation }
       Type Identifier <b>(</b> <b>)</b> [ <b>default</b> Expression ] <b>;</b>


==========================================

Changes to existing grammar rules (add Annotation where ever Modifiers can 
appear):


PackageDeclaration:
  { Annotation } <b>package</b> Name <b>;</b>

TypeDeclaration:
		ClassDeclaration
		InterfaceDeclaration
		EnumDeclaration
ClassDeclaration:
     [ Javadoc ] { Modifier | Annotation } <b>class</b> Identifier
		[ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } 
<b>&gt;</b> ]
		[ <b>extends</b> Type ]
		[ <b>implements</b> Type { <b>,</b> Type } ]
		<b>{</b> { ClassBodyDeclaration | <b>;</b> } <b>}</b>
InterfaceDeclaration:
     [ Javadoc ] { Modifier | Annotation } <b>interface</b> Identifier
		[ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } 
<b>&gt;</b> ]
		[ <b>extends</b> Type { <b>,</b> Type } ]
			<b>{</b> { InterfaceBodyDeclaration | <b>;</b> } <b>}
</b>
EnumDeclaration:
     [ Javadoc ] { Modifier | Annotation } <b>enum</b> Identifier
		[ <b>implements</b> Type { <b>,</b> Type } ]
		<b>{</b>
                [ EnumConstantDeclaration [ <b>,</b> 
EnumConstantDeclaration ] ]
                [ <b>;</b> { ClassBodyDeclaration | <b>;</b> } ]
         <b>}</b>

MethodDeclaration:
   [ Javadoc ] { Modifier | Annotation }
	  [ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ]
       ( Type | <b>void</b> ) Identifier <b>(</b>
       [ FormalParameter 
		     { <b>,</b> FormalParameter } ] <b>)</b> {<b>[</b> <b>]
</b> }
       [ <b>throws</b> TypeName { <b>,</b> TypeName } ] ( Block | <b>;</b> )
ConstructorDeclaration:
   [ Javadoc ] { Modifier | Annotation } Identifier <b>(</b>
		  [ FormalParameter
			 { <b>,</b> FormalParameter } ] <b>)</b>
       [<b>throws</b> TypeName { <b>,</b> TypeName } ] Block

FieldDeclaration:
   [Javadoc] { Modifier | Annotation } Type VariableDeclarationFragment
        { <b>,</b> VariableDeclarationFragment } <b>;</b>


EnumConstantDeclaration:
     [ Javadoc ] { Annotation } Identifier
           [ <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b> ]
		  [ <b>{</b> { ClassBodyDeclaration | <b>;</b> } <b>}</b> ]


SingleVariableDeclaration:
   { Modifier | Annotation } Type Identifier { <b>[</b><b>]</b> } [ <b>=</b> 
Expression ]


VariableDeclarationStatement:
   { Modifier | Annotation } Type VariableDeclarationFragment 
       { <b>,</b> VariableDeclarationFragment } <b>;</b>

VariableDeclarationExpression:
   { Modifier | Annotation } Type VariableDeclarationFragment
        { <b>,</b> VariableDeclarationFragment } 


==========================================

New AST node types:


public abstract class Annotation extends ASTNode {
  public boolean isNormalAnnotation();
  public boolean isMarkerAnnotation();
  public boolean isSingleMemberAnnotation();
  public Name getTypeName();
  public void setTypeName(Name typeName);
}
  
public final class NormalAnnotation extends Annotation {
  public List<MemberValuePairs> values();
}

public final class MarkerAnnotation extends Annotation {
  // no further members
}

public final class SingleMemberAnnotation extends Annotation {
  public Expression getValue();
  public void setValue(Expression value);
}

public final class MemberValuePair extends ASTNode {
  public Name getName();
  public void setName(Name name);
  public Expression getValue();
  public void setValue(Expression value);
}

AST
  public static NormalAnnotation newNormalAnnotation();
  public static MarkerAnnotation newMarkerAnnotation();
  public static SingleMemberAnnotation newSingleMemberAnnotation();

ASTVisitor
  public boolean visit(NormalAnnotation node);
  public void endVisit(NormalAnnotation node);
  public boolean visit(MarkerAnnotation node);
  public void endVisit(MarkerAnnotation node);
  public boolean visit(SingleMemberAnnotation node);
  public void endVisit(SingleMemberAnnotation node);
  public boolean visit(MemberValuePair node);
  public void endVisit(MemberValuePair node);

ASTMatcher
  public boolean match(NormalAnnotation node, Object other);
  public boolean match(MarkerAnnotation node, Object other);
  public boolean match(SingleMemberAnnotation node, Object other);
  public boolean match(MemberValuePair node, Object other);

ASTNode
  public static final int NORMAL_ANNOTATION = ?;
  public static final int MARKER_ANNOTATION = ?;
  public static final int SINGLE_MEMBER_ANNOTATION = ?;

BodyDeclaration
  public List<Annotation> annotations();
  
PackageDeclaration
  public List<Annotation> annotations();

EnumConstantDeclaration
  public List<Annotation> annotations();

SingleVariableDeclaration
  public List<Annotation> annotations();

VariableDeclarationExpression
  public List<Annotation> annotations();

VariableDeclarationStatement
  public List<Annotation> annotations();


==========================================

Option #1 for handling annotation type declarations and
annotation type member declarations.

Annotation type declarations are a restricted form of interface
declaration, and can go anywhere a type declarations can. 
So just add a flag to TypeDeclaration and
use TypeDeclaration to represent annotation type declarations too:

TypeDeclaration
  public boolean isAnnotationType();
  public void setAnnotationType(boolean value);

Annotation type member declarations look a lot like 0-parameter method
declarations. So just add a default property to MethodDeclaration and
use MethodDeclaration to represent annotation type member declarations too:

MethodDeclaration
  public Expression getAnnotationDefault(); // may be null
  public void setAnnotationDefault(Expression defaultValue); // may be null

==========================================

Option #2 for handling annotation type declarations
and annotation type member declarations.

Create a new note type AnnotationTypeDeclaration for annotation type
declarations, and adjust the existing world so that AnnotationTypeDeclaration 
can be put anywhere a type declaration can.

Create a new note type AnnotationTypeMemberDeclaration for annotation type
member declarations.

public abstract class AbstractTypeDeclaration extends BodyDeclaration {
}

TypeDeclaration extends AbstractTypeDeclaration

CompilationUnit
  public List<AbstractTypeDeclaration> types(); // instead of 
List<TypeDeclaration>

public final class AnnotationTypeDeclaration extends AbstractTypeDeclaration {
  public SimpleName getName();
  public void setName(SimpleName name);
  public List<AnotationTypeMemberDeclaration> members();
}

public final class AnotationTypeMemberDeclaration extends ASTNode {
  public Javadoc getJavadoc(); // may be null
  public void setJavadoc(Javadoc doc);  // may be null
  public int getModifiers();
  public void setModifiers(int modifiers);
  public Type getType();
  public void setType(Type type);
  public SimpleName getName();
  public void setName(SimpleName name);
  public Expression getDefault(); // may be null
  public void setDefault(Expression defaultValue); // may be null
}

AST
  public static AnnotationTypeDeclaration newAnnotationTypeDeclaration();
  public static AnotationTypeMemberDeclaration 
newAnotationTypeMemberDeclaration();

ASTVisitor
  public boolean visit(AnnotationTypeDeclaration node);
  public void endVisit(AnnotationTypeDeclaration node);
  public boolean visit(AnotationTypeMemberDeclaration node);
  public void endVisit(AnotationTypeMemberDeclaration node);

ASTMatcher
  public boolean match(AnnotationTypeDeclaration node, Object other);
  public boolean match(AnotationTypeMemberDeclaration node, Object other);

ASTNode
  public static final int ANNOTATION_TYPE_DECLARATION = ?;
  public static final int ANNOTATION_TYPE_MEMBER_DECLARATION = ?;

Neither option #1 nor #2 are breaking changes for existing clients
provided they the source they are operating on does not use annotations.
(That is, the same as for the JST-014 and JSR-201 changes to DOM/AST.)

I'd be interested in input from the compiler team on whether there is
any difficulty in providing either #1 or #2. And I'd like to hear from
DOM/AST clients as to which option would better suit their particular needs.
Comment 2 Jim des Rivieres CLA 2004-01-22 19:32:30 EST
I should add that above sketch is based on the Public Review spec of JSR-175:
http://jcp.org/aboutJava/communityprocess/review/jsr175/index.html
Comment 3 Philipe Mulet CLA 2004-01-23 06:20:01 EST
Similarily to DOM AST support for innerclasses, I would think option #2 is the 
most appropriate as it provides a way for clients to specifically visit these 
types without affecting legacy code.
Comment 4 Olivier Thomann CLA 2004-01-23 08:48:32 EST
I also prefer the second approach.
Comment 5 Martin Aeschlimann CLA 2004-01-23 08:56:29 EST
I also favour #2 as the annotation types really seem to be different from 
normal types (no super types, only annotation type members) so merging them 
together will lead to confusion.

A suggestion I have is about the 'annotations()' API of nodes that can be 
annotated: From the grammar I see that you can mix modifiers and annotations in 
any order. ({Modifier | Annotation}. This would not be expressed in the AST. I 
would suggest that we now also introduce a node for a modifier.
I've brought up this DCR already once (bug 13995), to have modfier nodes would 
help in the rewriter to get clients give control about the order of modifiers.

Comment 6 Jim des Rivieres CLA 2004-01-23 11:22:08 EST
Consensus is to go with #2 and have separate AnnotationTypeDeclaration
and AnnotationTypeMemberDeclaration node types.

Martin makes an excellent suggestion that this is a good time to improve 
support for modifiers by handing them like annotations. Here's how I propose 
doing that:

Replace annotations() with:
  public List<ExtendedModifier> modifiers();

public abstract class ExtendedModifier extends ASTNode {
  public boolean isModifier();
  public boolean isAnnotation();
}

public abstract class Annotation extends ExtendedModifier {
  ... [no change]
}

public final class StandardModifier extends ExtendedModifier {
  public ModifierKind getKind();
  public void setKind(ModifierKind modifier);

  public static class ModifierKind() {   // enum
    public static final ModifierKind PUBLIC;
    public static final ModifierKind PROTECTED;
    public static final ModifierKind PRIVATE;
    public static final ModifierKind STATIC;
    public static final ModifierKind FINAL;
    public static final ModifierKind TRANSIENT;
    public static final ModifierKind STRICTFP;
    public static final ModifierKind SYNCHRONIZED;
    public static final ModifierKind NATIVE;
    public static final ModifierKind ABSTRACT;
    public static final ModifierKind VOLATILE;
    public String toString();
    public ModifierKind toKind(String modifier);
  }
}

We would deprecate the old modifier story (get/setFlags, Modifier). For 
backward compatibility, we would ensure that AST.parse* continues
to call setFlags.
Comment 7 Martin Aeschlimann CLA 2004-01-23 11:42:55 EST
I meant bug 23116, not bug 13995. Jim probably referred to set/getModifier, 
setFlags is a different thing.
Comment 8 Jim des Rivieres CLA 2004-01-23 12:29:29 EST
Yes. I meant to say that we would deprecate get/setModifiers and Modifier.
Comment 9 Jim des Rivieres CLA 2004-02-16 22:17:33 EST
I've added the support is the form outlined above, with the following notes:
- turned existing Modifier class into a node type rather that invent new 
StandardModifier
- moved up get/SetName() and bodyDeclarations() to AbstractTypeDeclaration
- introduce modifiers() on BodyDeclaration (and other places)
- moved up get/SetModifiers() to BodyDeclaration
- introduced EnumDeclaration as 3rd subclass of AbstractTypeDeclaration

Frederic/Olivier: Can you fix AST converter to create Modifier nodes
with source positions (that is, in addition to calls to XXX.setModifiers())?
Once this is changed, clients will be able to use the new XXX.modifiers(),
and I will deprecate XXX.get/setModifiers().

Comment 10 Jim des Rivieres CLA 2004-02-24 14:15:49 EST
I20040224 includes basic support for new and modified AST node types, incuding 
the ones for the new JSR-175 metadata/annotations. The new node types are 
available in the 3.0 version of the AST API. Note that there is no Java 
parser/compiler backing it yet, which means that AST.parse*() methods (now on 
new ASTParser class) do not yet support the 3.0 AST API.
Comment 11 Dan Rubel CLA 2004-08-11 12:46:41 EDT
The Eclipse.org Pollinate team needs annotation support as soon as its 
available. I glanced at build I20040727 and even though the editor complained 
about a simple annotation declaration, the compiler generated the class and the 
annotation type as an inner class (at least it looked that way at first blush). 
We can survive without editor annotation support for quite a while, but compiler 
support is much more critical. 

Can anyone comment on what compiler annotation support is available in M1 and 
what is planned after M1?
Comment 12 ilias CLA 2004-12-18 09:56:32 EST
According to the plan, this Issue should be "resolved":

http://dev.eclipse.org/viewcvs/index.cgi/%7Echeckout%7E/jdt-core-home/r3.1/main.html

The solved items on the plan still contain time-estimations.

This is missleading.
Comment 13 Jim des Rivieres CLA 2004-12-22 10:13:02 EST
Yes. DOM support for annotations is complete in the 3.1 stream. Closing.