011e820faf4d82fc1aa4ef5e8207aba3e1742e86
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / EnumConstantDeclaration.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.core.dom;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 /**
18  * Enumeration constant declaration AST node type (added in JLS3 API).
19  *
20  * <pre>
21  * EnumConstantDeclaration:
22  *     [ Javadoc ] { ExtendedModifier } Identifier
23  *         [ <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b> ]
24  *         [ AnonymousClassDeclaration ]
25  * </pre>
26  * <p>
27  * When a Javadoc comment is present, the source
28  * range begins with the first character of the "/**" comment delimiter.
29  * When there is no Javadoc comment, the source range begins with the first
30  * character of the identifier. If there are class body declarations, the
31  * source range extends through the last character of the last character of
32  * the "}" token following the body declarations. If there are arguments but
33  * no class body declarations, the source range extends through the last
34  * character of the ")" token following the arguments. If there are no 
35  * arguments and no class body declarations, the source range extends through
36  * the last character of the identifier.
37  * </p>
38  * 
39  * @since 3.1
40  * @noinstantiate This class is not intended to be instantiated by clients.
41  */
42 public class EnumConstantDeclaration extends BodyDeclaration {
43         
44         /**
45          * The "javadoc" structural property of this node type.
46          */
47         public static final ChildPropertyDescriptor JAVADOC_PROPERTY = 
48                 internalJavadocPropertyFactory(EnumConstantDeclaration.class);
49
50         /**
51          * The "modifiers" structural property of this node type).
52          */
53         public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
54                 internalModifiers2PropertyFactory(EnumConstantDeclaration.class);
55         
56         /**
57          * The "name" structural property of this node type.
58          */
59         public static final ChildPropertyDescriptor NAME_PROPERTY = 
60                 new ChildPropertyDescriptor(EnumConstantDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
61
62         /**
63          * The "arguments" structural property of this node type.
64          */
65         public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY = 
66                 new ChildListPropertyDescriptor(EnumConstantDeclaration.class, "arguments", Expression.class, NO_CYCLE_RISK); //$NON-NLS-1$
67         
68         /**
69          * The "anonymousClassDeclaration" structural property of this node type.
70          */
71         public static final ChildPropertyDescriptor ANONYMOUS_CLASS_DECLARATION_PROPERTY = 
72                 new ChildPropertyDescriptor(EnumConstantDeclaration.class, "anonymousClassDeclaration", AnonymousClassDeclaration.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
73         
74         /**
75          * A list of property descriptors (element type: 
76          * {@link StructuralPropertyDescriptor}),
77          * or null if uninitialized.
78          */
79         private static final List PROPERTY_DESCRIPTORS;
80         
81         static {
82                 List properyList = new ArrayList(6);
83                 createPropertyList(EnumConstantDeclaration.class, properyList);
84                 addProperty(JAVADOC_PROPERTY, properyList);
85                 addProperty(MODIFIERS2_PROPERTY, properyList);
86                 addProperty(NAME_PROPERTY, properyList);
87                 addProperty(ARGUMENTS_PROPERTY, properyList);
88                 addProperty(ANONYMOUS_CLASS_DECLARATION_PROPERTY, properyList);
89                 PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
90         }
91
92         /**
93          * Returns a list of structural property descriptors for this node type.
94          * Clients must not modify the result.
95          * 
96          * @param apiLevel the API level; one of the
97          * <code>AST.JLS*</code> constants
98
99          * @return a list of property descriptors (element type: 
100          * {@link StructuralPropertyDescriptor})
101          */
102         public static List propertyDescriptors(int apiLevel) {
103                 return PROPERTY_DESCRIPTORS;
104         }
105                         
106         /**
107          * The constant name; lazily initialized; defaults to a unspecified,
108          * legal Java class identifier.
109          */
110         private SimpleName constantName = null;
111
112         /**
113          * The list of argument expressions (element type: 
114          * <code>Expression</code>). Defaults to an empty list.
115          */
116         private ASTNode.NodeList arguments =
117                 new ASTNode.NodeList(ARGUMENTS_PROPERTY);
118                         
119         /**
120          * The optional anonymous class declaration; <code>null</code> for none; 
121          * defaults to none.
122          */
123         private AnonymousClassDeclaration optionalAnonymousClassDeclaration = null;
124         
125         /**
126          * Creates a new AST node for an enumeration constants declaration owned by
127          * the given AST. By default, the enumeration constant has an unspecified,
128          * but legal, name; no javadoc; an empty list of modifiers and annotations;
129          * an empty list of arguments; and does not declare an anonymous class.
130          * <p>
131          * N.B. This constructor is package-private; all subclasses must be 
132          * declared in the same package; clients are unable to declare 
133          * additional subclasses.
134          * </p>
135          * 
136          * @param ast the AST that is to own this node
137          */
138         EnumConstantDeclaration(AST ast) {
139                 super(ast);
140             unsupportedIn2();
141         }
142
143         /* (omit javadoc for this method)
144          * Method declared on ASTNode.
145          */
146         final List internalStructuralPropertiesForType(int apiLevel) {
147                 return propertyDescriptors(apiLevel);
148         }
149         
150         /* (omit javadoc for this method)
151          * Method declared on ASTNode.
152          */
153         final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
154                 if (property == JAVADOC_PROPERTY) {
155                         if (get) {
156                                 return getJavadoc();
157                         } else {
158                                 setJavadoc((Javadoc) child);
159                                 return null;
160                         }
161                 }
162                 if (property == NAME_PROPERTY) {
163                         if (get) {
164                                 return getName();
165                         } else {
166                                 setName((SimpleName) child);
167                                 return null;
168                         }
169                 }
170                 if (property == ANONYMOUS_CLASS_DECLARATION_PROPERTY) {
171                         if (get) {
172                                 return getAnonymousClassDeclaration();
173                         } else {
174                                 setAnonymousClassDeclaration((AnonymousClassDeclaration) child);
175                                 return null;
176                         }
177                 }
178                 // allow default implementation to flag the error
179                 return super.internalGetSetChildProperty(property, get, child);
180         }
181         
182         /* (omit javadoc for this method)
183          * Method declared on ASTNode.
184          */
185         final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
186                 if (property == MODIFIERS2_PROPERTY) {
187                         return modifiers();
188                 }
189                 if (property == ARGUMENTS_PROPERTY) {
190                         return arguments();
191                 }
192                 // allow default implementation to flag the error
193                 return super.internalGetChildListProperty(property);
194         }
195         
196         /* (omit javadoc for this method)
197          * Method declared on BodyDeclaration.
198          */
199         final ChildPropertyDescriptor internalJavadocProperty() {
200                 return JAVADOC_PROPERTY;
201         }
202
203         /* (omit javadoc for this method)
204          * Method declared on BodyDeclaration.
205          */
206         final ChildListPropertyDescriptor internalModifiers2Property() {
207                 return MODIFIERS2_PROPERTY;
208         }
209
210         /* (omit javadoc for this method)
211          * Method declared on BodyDeclaration.
212          */
213         final SimplePropertyDescriptor internalModifiersProperty() {
214                 // this property will not be asked for (node type did not exist in JLS2)
215                 return null;
216         }
217
218         /* (omit javadoc for this method)
219          * Method declared on ASTNode.
220          */
221         final int getNodeType0() {
222                 return ENUM_CONSTANT_DECLARATION;
223         }
224
225         /* (omit javadoc for this method)
226          * Method declared on ASTNode.
227          */
228         ASTNode clone0(AST target) {
229                 EnumConstantDeclaration result = new EnumConstantDeclaration(target);
230                 result.setSourceRange(this.getStartPosition(), this.getLength());
231                 result.setJavadoc(
232                         (Javadoc) ASTNode.copySubtree(target, getJavadoc()));
233                 result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
234                 result.setName((SimpleName) getName().clone(target));
235                 result.arguments().addAll(ASTNode.copySubtrees(target, arguments()));
236                 result.setAnonymousClassDeclaration(
237                                 (AnonymousClassDeclaration) ASTNode.copySubtree(target, getAnonymousClassDeclaration()));
238                 return result;
239         }
240
241         /* (omit javadoc for this method)
242          * Method declared on ASTNode.
243          */
244         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
245                 // dispatch to correct overloaded match method
246                 return matcher.match(this, other);
247         }
248         
249         /* (omit javadoc for this method)
250          * Method declared on ASTNode.
251          */
252         void accept0(ASTVisitor visitor) {
253                 boolean visitChildren = visitor.visit(this);
254                 if (visitChildren) {
255                         // visit children in normal left to right reading order
256                         acceptChild(visitor, getJavadoc());
257                         acceptChildren(visitor, this.modifiers);
258                         acceptChild(visitor, getName());
259                         acceptChildren(visitor, this.arguments);
260                         acceptChild(visitor, getAnonymousClassDeclaration());
261                 }
262                 visitor.endVisit(this);
263         }
264         
265         /**
266          * Returns the name of the constant declared in this enum declaration.
267          * 
268          * @return the constant name node
269          */ 
270         public SimpleName getName() {
271                 if (this.constantName == null) {
272                         // lazy init must be thread-safe for readers
273                         synchronized (this) {
274                                 if (this.constantName == null) {
275                                         preLazyInit();
276                                         this.constantName = new SimpleName(this.ast);
277                                         postLazyInit(this.constantName, NAME_PROPERTY);
278                                 }
279                         }
280                 }
281                 return this.constantName;
282         }
283                 
284         /**
285          * Sets the name of the constant declared in this enum declaration to the
286          * given name.
287          * 
288          * @param constantName the new constant name
289          * @exception IllegalArgumentException if:
290          * <ul>
291          * <li>the node belongs to a different AST</li>
292          * <li>the node already has a parent</li>
293          * </ul>
294          */ 
295         public void setName(SimpleName constantName) {
296                 if (constantName == null) {
297                         throw new IllegalArgumentException();
298                 }
299                 ASTNode oldChild = this.constantName;
300                 preReplaceChild(oldChild, constantName, NAME_PROPERTY);
301                 this.constantName = constantName;
302                 postReplaceChild(oldChild, constantName, NAME_PROPERTY);
303         }
304
305         /**
306          * Returns the live ordered list of argument expressions in this enumeration
307          * constant declaration. Note that an empty list of arguments is equivalent
308          * to not explicitly specifying arguments.
309          * 
310          * @return the live list of argument expressions 
311          *    (element type: <code>Expression</code>)
312          */ 
313         public List arguments() {
314                 return this.arguments;
315         }
316
317         /**
318          * Returns the anonymous class declaration introduced by this
319          * enum constant declaration, if it has one.
320          * 
321          * @return the anonymous class declaration, or <code>null</code> if none
322          */ 
323         public AnonymousClassDeclaration getAnonymousClassDeclaration() {
324                 return this.optionalAnonymousClassDeclaration;
325         }
326         
327         /**
328          * Sets whether this enum constant declaration declares
329          * an anonymous class (that is, has class body declarations).
330          * 
331          * @param decl the anonymous class declaration, or <code>null</code> 
332          *    if none
333          */ 
334         public void setAnonymousClassDeclaration(AnonymousClassDeclaration decl) {
335                 ASTNode oldChild = this.optionalAnonymousClassDeclaration;
336                 preReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
337                 this.optionalAnonymousClassDeclaration = decl;
338                 postReplaceChild(oldChild, decl, ANONYMOUS_CLASS_DECLARATION_PROPERTY);
339         }
340         
341         /**
342          * Resolves and returns the binding for the constructor invoked by this
343          * enum constant.
344          * <p>
345          * Note that bindings are generally unavailable unless requested when the
346          * AST is being built.
347          * </p>
348          * 
349          * @return the constructor binding, or <code>null</code> if the binding
350          *    cannot be resolved
351          */     
352         public IMethodBinding resolveConstructorBinding() {
353                 return this.ast.getBindingResolver().resolveConstructor(this);
354         }
355
356         /**
357          * Resolves and returns the field binding for this enum constant.
358          * <p>
359          * Note that bindings are generally unavailable unless requested when the
360          * AST is being built.
361          * </p>
362          * 
363          * @return the binding, or <code>null</code> if the binding cannot be 
364          *    resolved
365          */     
366         public IVariableBinding resolveVariable() {
367                 return this.ast.getBindingResolver().resolveVariable(this);
368         }
369                 
370         /* (omit javadoc for this method)
371          * Method declared on ASTNode.
372          */
373         int memSize() {
374                 return super.memSize() + 3 * 4;
375         }
376         
377         /* (omit javadoc for this method)
378          * Method declared on ASTNode.
379          */
380         int treeSize() {
381                 return
382                         memSize()
383                         + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
384                         + this.modifiers.listSize()
385                         + (this.constantName == null ? 0 : getName().treeSize())
386                         + this.arguments.listSize()
387                         + (this.optionalAnonymousClassDeclaration == null ? 0 : getAnonymousClassDeclaration().treeSize());
388         }
389 }
390