Community
Participate
Working Groups
JSR-175 (metadata) is a candidate for inclusion in J2SE 1.5. We should tentatively add support for metadata in DOM/AST.
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><</b> TypeParameter { <b>,</b> TypeParameter } <b>></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><</b> TypeParameter { <b>,</b> TypeParameter } <b>></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><</b> TypeParameter { <b>,</b> TypeParameter } <b>></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.
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
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.
I also prefer the second approach.
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.
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.
I meant bug 23116, not bug 13995. Jim probably referred to set/getModifier, setFlags is a different thing.
Yes. I meant to say that we would deprecate get/setModifiers and Modifier.
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().
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.
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?
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.
Yes. DOM support for annotations is complete in the 3.1 stream. Closing.