1 /*******************************************************************************
2 * Copyright (c) 2004, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package net.sourceforge.phpdt.core.dom;
13 import java.util.ArrayList;
14 import java.util.List;
17 * Annotation type member declaration AST node type (added in JLS3 API).
19 * AnnotationTypeMemberDeclaration:
20 * [ Javadoc ] { ExtendedModifier }
21 * Type Identifier <b>(</b> <b>)</b> [ <b>default</b> Expression ] <b>;</b>
24 * Note that annotation type member declarations are only meaningful as
25 * elements of {@link AnnotationTypeDeclaration#bodyDeclarations()}.
28 * When a Javadoc comment is present, the source
29 * range begins with the first character of the "/**" comment delimiter.
30 * When there is no Javadoc comment, the source range begins with the first
31 * character of the first modifier keyword (if modifiers),
32 * or the first character of the member type (no modifiers).
33 * The source range extends through the last character of the
38 * @noinstantiate This class is not intended to be instantiated by clients.
40 public class AnnotationTypeMemberDeclaration extends BodyDeclaration {
43 * The "javadoc" structural property of this node type.
45 public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
46 internalJavadocPropertyFactory(AnnotationTypeMemberDeclaration.class);
49 * The "modifiers" structural property of this node type.
51 public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
52 internalModifiers2PropertyFactory(AnnotationTypeMemberDeclaration.class);
55 * The "name" structural property of this node type.
57 public static final ChildPropertyDescriptor NAME_PROPERTY =
58 new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
61 * The "type" structural property of this node type.
63 public static final ChildPropertyDescriptor TYPE_PROPERTY =
64 new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
67 * The "default" structural property of this node type.
69 public static final ChildPropertyDescriptor DEFAULT_PROPERTY =
70 new ChildPropertyDescriptor(AnnotationTypeMemberDeclaration.class, "default", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
73 * A list of property descriptors (element type:
74 * {@link StructuralPropertyDescriptor}),
75 * or null if uninitialized.
77 private static final List PROPERTY_DESCRIPTORS;
80 List properyList = new ArrayList(6);
81 createPropertyList(AnnotationTypeMemberDeclaration.class, properyList);
82 addProperty(JAVADOC_PROPERTY, properyList);
83 addProperty(MODIFIERS2_PROPERTY, properyList);
84 addProperty(NAME_PROPERTY, properyList);
85 addProperty(TYPE_PROPERTY, properyList);
86 addProperty(DEFAULT_PROPERTY, properyList);
87 PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
91 * Returns a list of structural property descriptors for this node type.
92 * Clients must not modify the result.
94 * @param apiLevel the API level; one of the
95 * <code>AST.JLS*</code> constants
96 * @return a list of property descriptors (element type:
97 * {@link StructuralPropertyDescriptor})
99 public static List propertyDescriptors(int apiLevel) {
100 return PROPERTY_DESCRIPTORS;
104 * The member name; lazily initialized; defaults to an unspecified,
105 * legal Java identifier.
107 private SimpleName memberName = null;
110 * The member type; lazily initialized; defaults to int.
112 private Type memberType = null;
115 * The optional default expression; <code>null</code> for none; defaults to none.
117 private Expression optionalDefaultValue = null;
120 * Creates a new AST node for an annotation type member declaration owned
121 * by the given AST. By default, the declaration is for a member of an
122 * unspecified, but legal, name; no modifiers; no javadoc;
123 * an unspecified value type; and no default value.
125 * N.B. This constructor is package-private; all subclasses must be
126 * declared in the same package; clients are unable to declare
127 * additional subclasses.
130 * @param ast the AST that is to own this node
132 AnnotationTypeMemberDeclaration(AST ast) {
137 /* (omit javadoc for this method)
138 * Method declared on ASTNode.
140 final List internalStructuralPropertiesForType(int apiLevel) {
141 return propertyDescriptors(apiLevel);
144 /* (omit javadoc for this method)
145 * Method declared on ASTNode.
147 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
148 if (property == JAVADOC_PROPERTY) {
152 setJavadoc((Javadoc) child);
156 if (property == NAME_PROPERTY) {
160 setName((SimpleName) child);
164 if (property == NAME_PROPERTY) {
168 setName((SimpleName) child);
172 if (property == TYPE_PROPERTY) {
176 setType((Type) child);
180 if (property == DEFAULT_PROPERTY) {
184 setDefault((Expression) child);
188 // allow default implementation to flag the error
189 return super.internalGetSetChildProperty(property, get, child);
192 /* (omit javadoc for this method)
193 * Method declared on ASTNode.
195 final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
196 if (property == MODIFIERS2_PROPERTY) {
199 // allow default implementation to flag the error
200 return super.internalGetChildListProperty(property);
203 /* (omit javadoc for this method)
204 * Method declared on BodyDeclaration.
206 final ChildPropertyDescriptor internalJavadocProperty() {
207 return JAVADOC_PROPERTY;
210 /* (omit javadoc for this method)
211 * Method declared on BodyDeclaration.
213 final ChildListPropertyDescriptor internalModifiers2Property() {
214 return MODIFIERS2_PROPERTY;
217 /* (omit javadoc for this method)
218 * Method declared on BodyDeclaration.
220 final SimplePropertyDescriptor internalModifiersProperty() {
221 // this property will not be asked for (node type did not exist in JLS2)
225 /* (omit javadoc for this method)
226 * Method declared on ASTNode.
228 final int getNodeType0() {
229 return ANNOTATION_TYPE_MEMBER_DECLARATION;
232 /* (omit javadoc for this method)
233 * Method declared on ASTNode.
235 ASTNode clone0(AST target) {
236 AnnotationTypeMemberDeclaration result = new AnnotationTypeMemberDeclaration(target);
237 result.setSourceRange(this.getStartPosition(), this.getLength());
239 (Javadoc) ASTNode.copySubtree(target, getJavadoc()));
240 result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
241 result.setType((Type) ASTNode.copySubtree(target, getType()));
242 result.setName((SimpleName) getName().clone(target));
243 result.setDefault((Expression) ASTNode.copySubtree(target, getDefault()));
247 /* (omit javadoc for this method)
248 * Method declared on ASTNode.
250 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
251 // dispatch to correct overloaded match method
252 return matcher.match(this, other);
255 /* (omit javadoc for this method)
256 * Method declared on ASTNode.
258 void accept0(ASTVisitor visitor) {
259 boolean visitChildren = visitor.visit(this);
261 // visit children in normal left to right reading order
262 acceptChild(visitor, getJavadoc());
263 acceptChildren(visitor, this.modifiers);
264 acceptChild(visitor, getType());
265 acceptChild(visitor, getName());
266 acceptChild(visitor, getDefault());
268 visitor.endVisit(this);
272 * Returns the name of the annotation type member declared in this declaration.
274 * @return the member name node
276 public SimpleName getName() {
277 if (this.memberName == null) {
278 // lazy init must be thread-safe for readers
279 synchronized (this) {
280 if (this.memberName == null) {
282 this.memberName = new SimpleName(this.ast);
283 postLazyInit(this.memberName, NAME_PROPERTY);
287 return this.memberName;
291 * Sets the name of the annotation type member declared in this declaration to the
294 * @param memberName the new member name
295 * @exception IllegalArgumentException if:
297 * <li>the node belongs to a different AST</li>
298 * <li>the node already has a parent</li>
301 public void setName(SimpleName memberName) {
302 if (memberName == null) {
303 throw new IllegalArgumentException();
305 ASTNode oldChild = this.memberName;
306 preReplaceChild(oldChild, memberName, NAME_PROPERTY);
307 this.memberName = memberName;
308 postReplaceChild(oldChild, memberName, NAME_PROPERTY);
312 * Returns the type of the annotation type member declared in this
315 * @return the type of the member
317 public Type getType() {
318 if (this.memberType == null) {
319 // lazy init must be thread-safe for readers
320 synchronized (this) {
321 if (this.memberType == null) {
323 this.memberType = this.ast.newPrimitiveType(PrimitiveType.INT);
324 postLazyInit(this.memberType, TYPE_PROPERTY);
328 return this.memberType;
332 * Sets the type of the annotation type member declared in this declaration
335 * @param type the new member type
336 * @exception IllegalArgumentException if:
338 * <li>the node belongs to a different AST</li>
339 * <li>the node already has a parent</li>
342 public void setType(Type type) {
344 throw new IllegalArgumentException();
346 ASTNode oldChild = this.memberType;
347 preReplaceChild(oldChild, type, TYPE_PROPERTY);
348 this.memberType = type;
349 postReplaceChild(oldChild, type, TYPE_PROPERTY);
353 * Returns the default value of this annotation type member, or
354 * <code>null</code> if there is none.
356 * @return the expression node, or <code>null</code> if there is none
358 public Expression getDefault() {
359 return this.optionalDefaultValue;
363 * Sets or clears the default value of this annotation type member.
365 * @param defaultValue the expression node, or <code>null</code> if
367 * @exception IllegalArgumentException if:
369 * <li>the node belongs to a different AST</li>
370 * <li>the node already has a parent</li>
371 * <li>a cycle in would be created</li>
374 public void setDefault(Expression defaultValue) {
375 // a AnnotationTypeMemberDeclaration may occur inside an Expression - must check cycles
376 ASTNode oldChild = this.optionalDefaultValue;
377 preReplaceChild(oldChild, defaultValue, DEFAULT_PROPERTY);
378 this.optionalDefaultValue = defaultValue;
379 postReplaceChild(oldChild, defaultValue, DEFAULT_PROPERTY);
383 * Resolves and returns the binding for the annotation type member declared
384 * in this declaration.
386 * Note that bindings are generally unavailable unless requested when the
387 * AST is being built.
390 * @return the binding, or <code>null</code> if the binding cannot be
393 public IMethodBinding resolveBinding() {
394 return this.ast.getBindingResolver().resolveMember(this);
397 /* (omit javadoc for this method)
398 * Method declared on ASTNode.
401 return super.memSize() + 3 * 4;
404 /* (omit javadoc for this method)
405 * Method declared on ASTNode.
410 + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
411 + this.modifiers.listSize()
412 + (this.memberName == null ? 0 : getName().treeSize())
413 + (this.memberType == null ? 0 : getType().treeSize())
414 + (this.optionalDefaultValue == null ? 0 : getDefault().treeSize());