0a437ac21072e4e27d8f55c5971f32a22a05683a
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / VariableDeclarationFragment.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  * Variable declaration fragment AST node type, used in field declarations, 
19  * local variable declarations, and <code>ForStatement</code> initializers.
20  * It contrast to <code>SingleVariableDeclaration</code>, fragments are
21  * missing the modifiers and the type; these are located in the fragment's
22  * parent node.
23  *
24  * <pre>
25  * VariableDeclarationFragment:
26  *    Identifier { <b>[</b><b>]</b> } [ <b>=</b> Expression ]
27  * </pre>
28  * 
29  * @since 2.0
30  * @noinstantiate This class is not intended to be instantiated by clients.
31  */
32 public class VariableDeclarationFragment extends VariableDeclaration {
33                 
34         /**
35          * The "name" structural property of this node type.
36          * @since 3.0
37          */
38         public static final ChildPropertyDescriptor NAME_PROPERTY = 
39                 new ChildPropertyDescriptor(VariableDeclarationFragment.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
40
41         /**
42          * The "extraDimensions" structural property of this node type.
43          * @since 3.0
44          */
45         public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY = 
46                 new SimplePropertyDescriptor(VariableDeclarationFragment.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$
47         
48         /**
49          * The "initializer" structural property of this node type.
50          * @since 3.0
51          */
52         public static final ChildPropertyDescriptor INITIALIZER_PROPERTY = 
53                 new ChildPropertyDescriptor(VariableDeclarationFragment.class, "initializer", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
54
55         /**
56          * A list of property descriptors (element type: 
57          * {@link StructuralPropertyDescriptor}),
58          * or null if uninitialized.
59          * @since 3.0
60          */
61         private static final List PROPERTY_DESCRIPTORS;
62                 
63         static {
64                 List propertyList = new ArrayList(4);
65                 createPropertyList(VariableDeclarationFragment.class, propertyList);
66                 addProperty(NAME_PROPERTY, propertyList);
67                 addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
68                 addProperty(INITIALIZER_PROPERTY, propertyList);
69                 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
70         }
71
72         /**
73          * Returns a list of structural property descriptors for this node type.
74          * Clients must not modify the result.
75          * 
76          * @param apiLevel the API level; one of the
77          * <code>AST.JLS*</code> constants
78          * @return a list of property descriptors (element type: 
79          * {@link StructuralPropertyDescriptor})
80          * @since 3.0
81          */
82         public static List propertyDescriptors(int apiLevel) {
83                 return PROPERTY_DESCRIPTORS;
84         }
85                         
86         /**
87          * The variable name; lazily initialized; defaults to an unspecified,
88          * legal Java identifier.
89          */
90         private SimpleName variableName = null;
91
92         /**
93          * The number of extra array dimensions that this variable has;
94          * defaults to 0.
95          */
96         private int extraArrayDimensions = 0;
97
98         /**
99          * The initializer expression, or <code>null</code> if none;
100          * defaults to none.
101          */
102         private Expression optionalInitializer = null;
103         
104         /**
105          * Creates a new AST node for a variable declaration fragment owned by the 
106          * given AST. By default, the variable declaration has: an unspecified 
107          * (but legal) variable name, no initializer, and no extra array dimensions.
108          * <p>
109          * N.B. This constructor is package-private.
110          * </p>
111          * 
112          * @param ast the AST that is to own this node
113          */
114         VariableDeclarationFragment(AST ast) {
115                 super(ast);
116         }
117
118         /* (omit javadoc for this method)
119          * Method declared on VariableDeclaration.
120          * @since 3.1
121          */
122         final SimplePropertyDescriptor internalExtraDimensionsProperty() {
123                 return EXTRA_DIMENSIONS_PROPERTY;
124         }
125
126         /* (omit javadoc for this method)
127          * Method declared on VariableDeclaration.
128          * @since 3.1
129          */
130         final ChildPropertyDescriptor internalInitializerProperty() {
131                 return INITIALIZER_PROPERTY;
132         }
133
134         /* (omit javadoc for this method)
135          * Method declared on VariableDeclaration.
136          * @since 3.1
137          */
138         final ChildPropertyDescriptor internalNameProperty() {
139                 return NAME_PROPERTY;
140         }
141
142         /* (omit javadoc for this method)
143          * Method declared on ASTNode.
144          */
145         final List internalStructuralPropertiesForType(int apiLevel) {
146                 return propertyDescriptors(apiLevel);
147         }
148         
149         /* (omit javadoc for this method)
150          * Method declared on ASTNode.
151          */
152         final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
153                 if (property == EXTRA_DIMENSIONS_PROPERTY) {
154                         if (get) {
155                                 return getExtraDimensions();
156                         } else {
157                                 setExtraDimensions(value);
158                                 return 0;
159                         }
160                 }
161                 // allow default implementation to flag the error
162                 return super.internalGetSetIntProperty(property, get, value);
163         }
164         
165         /* (omit javadoc for this method)
166          * Method declared on ASTNode.
167          */
168         final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
169                 if (property == NAME_PROPERTY) {
170                         if (get) {
171                                 return getName();
172                         } else {
173                                 setName((SimpleName) child);
174                                 return null;
175                         }
176                 }
177                 if (property == INITIALIZER_PROPERTY) {
178                         if (get) {
179                                 return getInitializer();
180                         } else {
181                                 setInitializer((Expression) child);
182                                 return null;
183                         }
184                 }
185                 // allow default implementation to flag the error
186                 return super.internalGetSetChildProperty(property, get, child);
187         }
188         
189         /* (omit javadoc for this method)
190          * Method declared on ASTNode.
191          */
192         final int getNodeType0() {
193                 return VARIABLE_DECLARATION_FRAGMENT;
194         }
195
196         /* (omit javadoc for this method)
197          * Method declared on ASTNode.
198          */
199         ASTNode clone0(AST target) {
200                 VariableDeclarationFragment result = new VariableDeclarationFragment(target);
201                 result.setSourceRange(this.getStartPosition(), this.getLength());
202                 result.setName((SimpleName) getName().clone(target));
203                 result.setExtraDimensions(getExtraDimensions());
204                 result.setInitializer(
205                         (Expression) ASTNode.copySubtree(target, getInitializer()));
206                 return result;
207         }
208
209         /* (omit javadoc for this method)
210          * Method declared on ASTNode.
211          */
212         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
213                 // dispatch to correct overloaded match method
214                 return matcher.match(this, other);
215         }
216
217         /* (omit javadoc for this method)
218          * Method declared on ASTNode.
219          */
220         void accept0(ASTVisitor visitor) {
221                 boolean visitChildren = visitor.visit(this);
222                 if (visitChildren) {
223                         // visit children in normal left to right reading order
224                         acceptChild(visitor, getName());
225                         acceptChild(visitor, getInitializer());
226                 }
227                 visitor.endVisit(this);
228         }
229         
230         /* (omit javadoc for this method)
231          * Method declared on VariableDeclaration.
232          */ 
233         public SimpleName getName() {
234                 if (this.variableName == null) {
235                         // lazy init must be thread-safe for readers
236                         synchronized (this) {
237                                 if (this.variableName == null) {
238                                         preLazyInit();
239                                         this.variableName = new SimpleName(this.ast);
240                                         postLazyInit(this.variableName, NAME_PROPERTY);
241                                 }
242                         }
243                 }
244                 return this.variableName;
245         }
246                 
247         /* (omit javadoc for this method)
248          * Method declared on VariableDeclaration.
249          */ 
250         public void setName(SimpleName variableName) {
251                 if (variableName == null) {
252                         throw new IllegalArgumentException();
253                 }
254                 ASTNode oldChild = this.variableName;
255                 preReplaceChild(oldChild, variableName, NAME_PROPERTY);
256                 this.variableName = variableName;
257                 postReplaceChild(oldChild, variableName, NAME_PROPERTY);
258         }
259
260         /**
261          * Returns the number of extra array dimensions this variable has over
262          * and above the type specified in the enclosing declaration.
263          * <p>
264          * For example, in the AST for <code>int[] i, j[], k[][]</code> the 
265          * variable declaration fragments for the variables <code>i</code>,
266          * <code>j</code>, and <code>k</code>, have 0, 1, and 2 extra array
267          * dimensions, respectively.
268          * </p>
269          * 
270          * @return the number of extra array dimensions this variable has over
271          *         and above the type specified in the enclosing declaration
272          * @since 2.0
273          */ 
274         public int getExtraDimensions() {
275                 return this.extraArrayDimensions;
276         }
277
278         /**
279          * Sets the number of extra array dimensions this variable has over
280          * and above the type specified in the enclosing declaration.
281          * <p>
282          * For example, in the AST for <code>int[] i, j[], k[][]</code> the 
283          * variable declaration fragments for the variables <code>i</code>,
284          * <code>j</code>, and <code>k</code>, have 0, 1, and 2 extra array
285          * dimensions, respectively.
286          * </p>
287          * 
288          * @param dimensions the given dimensions
289          * @since 2.0
290          */ 
291         public void setExtraDimensions(int dimensions) {
292                 if (dimensions < 0) {
293                         throw new IllegalArgumentException();
294                 }
295                 preValueChange(EXTRA_DIMENSIONS_PROPERTY);
296                 this.extraArrayDimensions = dimensions;
297                 postValueChange(EXTRA_DIMENSIONS_PROPERTY);
298         }
299
300         /* (omit javadoc for this method)
301          * Method declared on VariableDeclaration.
302          */ 
303         public Expression getInitializer() {
304                 return this.optionalInitializer;
305         }
306         
307         /* (omit javadoc for this method)
308          * Method declared on VariableDeclaration.
309          */ 
310         public void setInitializer(Expression initializer) {
311                 ASTNode oldChild = this.optionalInitializer;
312                 preReplaceChild(oldChild, initializer, INITIALIZER_PROPERTY);
313                 this.optionalInitializer = initializer;
314                 postReplaceChild(oldChild, initializer, INITIALIZER_PROPERTY);
315         }
316
317         /* (omit javadoc for this method)
318          * Method declared on ASTNode.
319          */
320         int memSize() {
321                 // treat Operator as free
322                 return BASE_NODE_SIZE + 3 * 4;
323         }
324         
325         /* (omit javadoc for this method)
326          * Method declared on ASTNode.
327          */
328         int treeSize() {
329                 return 
330                         memSize()
331                         + (this.variableName == null ? 0 : getName().treeSize())
332                         + (this.optionalInitializer == null ? 0 : getInitializer().treeSize());
333         }
334 }