9c0ab01935f1782c439f35244e5b73e096f706f7
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / BodyDeclaration.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.Iterator;
15 import java.util.List;
16
17 /**
18  * Abstract base class of all AST nodes that represent body declarations 
19  * that may appear in the body of some kind of class or interface declaration,
20  * including anonymous class declarations, enumeration declarations, and
21  * enumeration constant declarations.
22  * <p>
23  * For JLS2:
24  * <pre>
25  * BodyDeclaration:
26  *              ClassDeclaration
27  *              InterfaceDeclaration
28  *              MethodDeclaration
29  *              ConstructorDeclaration
30  *              FieldDeclaration
31  *              Initializer
32  * </pre>
33  * For JLS3, a number of new node types were introduced:
34  * <pre>
35  * BodyDeclaration:
36  *              ClassDeclaration
37  *              InterfaceDeclaration
38  *              EnumDeclaration
39  *              MethodDeclaration
40  *              ConstructorDeclaration
41  *              FieldDeclaration
42  *              Initializer
43  *              EnumConstantDeclaration
44  *              AnnotationTypeDeclaration
45  *              AnnotationTypeMemberDeclaration
46  * </pre>
47  * </p>
48  * <p>
49  * All types of body declarations carry modifiers (and annotations), although they differ in
50  * which modifiers are allowed. Most types of body declarations can carry a
51  * doc comment; Initializer is the only ones that does not. The source range
52  * for body declarations always includes the doc comment if present.
53  * </p>
54  * 
55  * @since 2.0
56  */
57 public abstract class BodyDeclaration extends ASTNode {
58         
59         /**
60          * The doc comment, or <code>null</code> if none.
61          * Defaults to none.
62          */
63         Javadoc optionalDocComment = null;
64
65         /**
66          * The modifier flags; bit-wise or of Modifier flags.
67          * Defaults to none. Not used in 3.0.
68          * @since 3.0 - field was moved up from subclasses
69          */
70         private int modifierFlags = Modifier.NONE;
71         
72         /**
73          * The extended modifiers (element type: <code>IExtendedModifier</code>). 
74          * Null in JLS2. Added in JLS3; defaults to an empty list
75          * (see constructor).
76          * 
77          * @since 3.0
78          */
79         ASTNode.NodeList modifiers = null;
80         
81         /**
82          * Returns structural property descriptor for the "modifiers" property
83          * of this node as used in JLS2.
84          * 
85          * @return the property descriptor
86          */
87         abstract SimplePropertyDescriptor internalModifiersProperty();
88
89         /**
90          * Returns structural property descriptor for the "modifiers" property
91          * of this node as used in JLS3.
92          * 
93          * @return the property descriptor
94          */
95         abstract ChildListPropertyDescriptor internalModifiers2Property();
96
97         /**
98          * Returns structural property descriptor for the "modifiers" property
99          * of this node as used in JLS3.
100          * 
101          * @return the property descriptor
102          * @since 3.1
103          */
104         public final ChildListPropertyDescriptor getModifiersProperty() {
105                 // important: return property for AST.JLS3
106                 return internalModifiers2Property();
107         }
108
109         /**
110          * Returns structural property descriptor for the "javadoc" property
111          * of this node.
112          * 
113          * @return the property descriptor
114          */
115         abstract ChildPropertyDescriptor internalJavadocProperty();
116
117         /**
118          * Returns structural property descriptor for the "javadoc" property
119          * of this node.
120          * 
121          * @return the property descriptor
122          * @since 3.1
123          */
124         public final ChildPropertyDescriptor getJavadocProperty() {
125                 return internalJavadocProperty();
126         }
127
128         /**
129          * Creates and returns a structural property descriptor for the
130          * "javadoc" property declared on the given concrete node type.
131          * 
132          * @return the property descriptor
133          */
134         static final ChildPropertyDescriptor internalJavadocPropertyFactory(Class nodeClass) {
135                 return new ChildPropertyDescriptor(nodeClass, "javadoc", Javadoc.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
136         }
137         
138         /**
139          * Creates and returns a structural property descriptor for the
140          * "modifiers" property declared on the given concrete node type.
141          * 
142          * @return the property descriptor
143          */
144         static final SimplePropertyDescriptor internalModifiersPropertyFactory(Class nodeClass) {
145                 return new SimplePropertyDescriptor(nodeClass, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
146         }
147         
148         /**
149          * Creates and returns a structural property descriptor for the
150          * "modifiers" property declared on the given concrete node type.
151          * 
152          * @return the property descriptor
153          */
154         static final ChildListPropertyDescriptor internalModifiers2PropertyFactory(Class nodeClass) {
155                 return new ChildListPropertyDescriptor(nodeClass, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
156         }
157         
158         /**
159          * Creates a new AST node for a body declaration node owned by the 
160          * given AST.
161          * <p>
162          * N.B. This constructor is package-private.
163          * </p>
164          * 
165          * @param ast the AST that is to own this node
166          */
167         BodyDeclaration(AST ast) {
168                 super(ast);
169                 if (ast.apiLevel >= AST.JLS3) {
170                         this.modifiers = new ASTNode.NodeList(internalModifiers2Property());
171                 }
172         }
173         
174         /**
175          * Returns the doc comment node.
176          * 
177          * @return the doc comment node, or <code>null</code> if none
178          */
179         public Javadoc getJavadoc() {
180                 return this.optionalDocComment;
181         }
182
183         /**
184          * Sets or clears the doc comment node.
185          * 
186          * @param docComment the doc comment node, or <code>null</code> if none
187          * @exception IllegalArgumentException if the doc comment string is invalid
188          */
189         public void setJavadoc(Javadoc docComment) {
190                 ChildPropertyDescriptor p = internalJavadocProperty();
191                 ASTNode oldChild = this.optionalDocComment;
192                 preReplaceChild(oldChild, docComment, p);
193                 this.optionalDocComment = docComment;
194                 postReplaceChild(oldChild, docComment, p);
195         }
196
197         /**
198          * Returns the modifiers explicitly specified on this declaration.
199          * <p>
200          * In the JLS3 API, this method is a convenience method that
201          * computes these flags from <code>modifiers()</code>.
202          * </p>
203          * 
204          * @return the bit-wise or of <code>Modifier</code> constants
205          * @see Modifier
206          */ 
207         public int getModifiers() {
208                 // more efficient than checking getAST().API_LEVEL
209                 if (this.modifiers == null) {
210                         // JLS2 behavior - bona fide property
211                         return this.modifierFlags;
212                 } else {
213                         // JLS3 behavior - convenience method
214                         // performance could be improved by caching computed flags
215                         // but this would require tracking changes to this.modifiers
216                         int computedmodifierFlags = Modifier.NONE;
217                         for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
218                                 Object x = it.next();
219                                 if (x instanceof Modifier) {
220                                         computedmodifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
221                                 }
222                         }
223                         return computedmodifierFlags;
224                 }
225         }
226
227         /**
228          * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
229          * 
230          * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
231          * @exception UnsupportedOperationException if this operation is used in
232          * an AST later than JLS2
233          * @see Modifier
234          * @deprecated In the JLS3 API, this method is replaced by 
235          * {@link #modifiers()} which contains a list of a <code>Modifier</code> nodes.
236          */ 
237         public void setModifiers(int modifiers) {
238                 internalSetModifiers(modifiers);
239         }
240         
241         /**
242          * Internal synonym for deprecated method. Used to avoid
243          * deprecation warnings.
244          * @since 3.1
245          */
246         /*package*/ final void internalSetModifiers(int pmodifiers) {
247                 // more efficient than just calling supportedOnlyIn2() to check
248                 if (this.modifiers != null) {
249                         supportedOnlyIn2();
250                 }
251                 SimplePropertyDescriptor p = internalModifiersProperty();
252                 preValueChange(p);
253                 this.modifierFlags = pmodifiers;
254                 postValueChange(p);
255         }
256
257         /**
258          * Returns the live ordered list of modifiers and annotations
259          * of this declaration (added in JLS3 API).
260          * 
261          * @return the live list of modifiers and annotations
262          *    (element type: <code>IExtendedModifier</code>)
263          * @exception UnsupportedOperationException if this operation is used in
264          * a JLS2 AST
265          * @since 3.1
266          */ 
267         public List modifiers() {
268                 // more efficient than just calling unsupportedIn2() to check
269                 if (this.modifiers == null) {
270                         unsupportedIn2();
271                 }
272                 return this.modifiers;
273         }
274         
275         /* (omit javadoc for this method)
276          * Method declared on ASTNode.
277          */
278         int memSize() {
279                 return BASE_NODE_SIZE + 3 * 4;
280         }
281 }
282