KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > VariableDeclarationExpression


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 org.eclipse.jdt.core.dom;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.Iterator JavaDoc;
16 import java.util.List JavaDoc;
17
18 /**
19  * Local variable declaration expression AST node type.
20  * <p>
21  * This kind of node collects together several variable declaration fragments
22  * (<code>VariableDeclarationFragment</code>) into a single expression
23  * (<code>Expression</code>), all sharing the same modifiers and base type.
24  * This type of node can be used as the initializer of a
25  * <code>ForStatement</code>, or wrapped in an <code>ExpressionStatement</code>
26  * to form the equivalent of a <code>VariableDeclarationStatement</code>.
27  * </p>
28  * For JLS2:
29  * <pre>
30  * VariableDeclarationExpression:
31  * { Modifier } Type VariableDeclarationFragment
32  * { <b>,</b> VariableDeclarationFragment }
33  * </pre>
34  * For JLS3, the modifier flags were replaced by
35  * a list of modifier nodes (intermixed with annotations):
36  * <pre>
37  * VariableDeclarationExpression:
38  * { ExtendedModifier } Type VariableDeclarationFragment
39  * { <b>,</b> VariableDeclarationFragment }
40  * </pre>
41  *
42  * @since 2.0
43  */

44 public class VariableDeclarationExpression extends Expression {
45
46     /**
47      * The "modifiers" structural property of this node type (JLS2 API only).
48      * @since 3.0
49      */

50     public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
51         new SimplePropertyDescriptor(VariableDeclarationExpression.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
52

53     /**
54      * The "modifiers" structural property of this node type (added in JLS3 API).
55      * @since 3.1
56      */

57     public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
58         new ChildListPropertyDescriptor(VariableDeclarationExpression.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
59

60     /**
61      * The "type" structural property of this node type.
62      * @since 3.0
63      */

64     public static final ChildPropertyDescriptor TYPE_PROPERTY =
65         new ChildPropertyDescriptor(VariableDeclarationExpression.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
66

67     /**
68      * The "fragments" structural property of this node type).
69      * @since 3.0
70      */

71     public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY =
72         new ChildListPropertyDescriptor(VariableDeclarationExpression.class, "fragments", VariableDeclarationFragment.class, CYCLE_RISK); //$NON-NLS-1$
73

74     /**
75      * A list of property descriptors (element type:
76      * {@link StructuralPropertyDescriptor}),
77      * or null if uninitialized.
78      * @since 3.0
79      */

80     private static final List JavaDoc PROPERTY_DESCRIPTORS_2_0;
81     
82     /**
83      * A list of property descriptors (element type:
84      * {@link StructuralPropertyDescriptor}),
85      * or null if uninitialized.
86      * @since 3.1
87      */

88     private static final List JavaDoc PROPERTY_DESCRIPTORS_3_0;
89     
90     static {
91         List JavaDoc propertyList = new ArrayList JavaDoc(4);
92         createPropertyList(VariableDeclarationExpression.class, propertyList);
93         addProperty(MODIFIERS_PROPERTY, propertyList);
94         addProperty(TYPE_PROPERTY, propertyList);
95         addProperty(FRAGMENTS_PROPERTY, propertyList);
96         PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
97         
98         propertyList = new ArrayList JavaDoc(4);
99         createPropertyList(VariableDeclarationExpression.class, propertyList);
100         addProperty(MODIFIERS2_PROPERTY, propertyList);
101         addProperty(TYPE_PROPERTY, propertyList);
102         addProperty(FRAGMENTS_PROPERTY, propertyList);
103         PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
104     }
105
106     /**
107      * Returns a list of structural property descriptors for this node type.
108      * Clients must not modify the result.
109      *
110      * @param apiLevel the API level; one of the
111      * <code>AST.JLS*</code> constants
112
113      * @return a list of property descriptors (element type:
114      * {@link StructuralPropertyDescriptor})
115      * @since 3.0
116      */

117     public static List JavaDoc propertyDescriptors(int apiLevel) {
118         if (apiLevel == AST.JLS2_INTERNAL) {
119             return PROPERTY_DESCRIPTORS_2_0;
120         } else {
121             return PROPERTY_DESCRIPTORS_3_0;
122         }
123     }
124             
125     /**
126      * The extended modifiers (element type: <code>IExtendedModifier</code>).
127      * Null in JLS2. Added in JLS3; defaults to an empty list
128      * (see constructor).
129      * @since 3.0
130      */

131     private ASTNode.NodeList modifiers = null;
132     
133     /**
134      * The modifier flags; bit-wise or of Modifier flags.
135      * Defaults to none. Not used in 3.0.
136      */

137     private int modifierFlags = Modifier.NONE;
138         
139     /**
140      * The base type; lazily initialized; defaults to an unspecified,
141      * legal type.
142      */

143     private Type baseType = null;
144
145     /**
146      * The list of variable declaration fragments (element type:
147      * <code VariableDeclarationFragment</code>). Defaults to an empty list.
148      */

149     private ASTNode.NodeList variableDeclarationFragments =
150         new ASTNode.NodeList(FRAGMENTS_PROPERTY);
151
152     /**
153      * Creates a new unparented local variable declaration expression node
154      * owned by the given AST. By default, the variable declaration has: no
155      * modifiers, an unspecified (but legal) type, and an empty list of variable
156      * declaration fragments (which is syntactically illegal).
157      * <p>
158      * N.B. This constructor is package-private.
159      * </p>
160      *
161      * @param ast the AST that is to own this node
162      */

163     VariableDeclarationExpression(AST ast) {
164         super(ast);
165         if (ast.apiLevel >= AST.JLS3) {
166             this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
167         }
168     }
169
170     /* (omit javadoc for this method)
171      * Method declared on ASTNode.
172      */

173     final List JavaDoc internalStructuralPropertiesForType(int apiLevel) {
174         return propertyDescriptors(apiLevel);
175     }
176     
177     /* (omit javadoc for this method)
178      * Method declared on ASTNode.
179      */

180     final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
181         if (property == MODIFIERS_PROPERTY) {
182             if (get) {
183                 return getModifiers();
184             } else {
185                 setModifiers(value);
186                 return 0;
187             }
188         }
189         // allow default implementation to flag the error
190
return super.internalGetSetIntProperty(property, get, value);
191     }
192     
193     /* (omit javadoc for this method)
194      * Method declared on ASTNode.
195      */

196     final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
197         if (property == TYPE_PROPERTY) {
198             if (get) {
199                 return getType();
200             } else {
201                 setType((Type) child);
202                 return null;
203             }
204         }
205         // allow default implementation to flag the error
206
return super.internalGetSetChildProperty(property, get, child);
207     }
208     
209     /* (omit javadoc for this method)
210      * Method declared on ASTNode.
211      */

212     final List JavaDoc internalGetChildListProperty(ChildListPropertyDescriptor property) {
213         if (property == MODIFIERS2_PROPERTY) {
214             return modifiers();
215         }
216         if (property == FRAGMENTS_PROPERTY) {
217             return fragments();
218         }
219         // allow default implementation to flag the error
220
return super.internalGetChildListProperty(property);
221     }
222     
223     /* (omit javadoc for this method)
224      * Method declared on ASTNode.
225      */

226     final int getNodeType0() {
227         return VARIABLE_DECLARATION_EXPRESSION;
228     }
229
230     /* (omit javadoc for this method)
231      * Method declared on ASTNode.
232      */

233     ASTNode clone0(AST target) {
234         VariableDeclarationExpression result =
235             new VariableDeclarationExpression(target);
236         result.setSourceRange(this.getStartPosition(), this.getLength());
237         if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
238             result.setModifiers(getModifiers());
239         }
240         if (this.ast.apiLevel >= AST.JLS3) {
241             result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
242         }
243         result.setType((Type) getType().clone(target));
244         result.fragments().addAll(
245             ASTNode.copySubtrees(target, fragments()));
246         return result;
247
248     }
249     
250     /* (omit javadoc for this method)
251      * Method declared on ASTNode.
252      */

253     final boolean subtreeMatch0(ASTMatcher matcher, Object JavaDoc other) {
254         // dispatch to correct overloaded match method
255
return matcher.match(this, other);
256     }
257
258     /* (omit javadoc for this method)
259      * Method declared on ASTNode.
260      */

261     void accept0(ASTVisitor visitor) {
262         boolean visitChildren = visitor.visit(this);
263         if (visitChildren) {
264             // visit children in normal left to right reading order
265
if (this.ast.apiLevel >= AST.JLS3) {
266                 acceptChildren(visitor, this.modifiers);
267             }
268             acceptChild(visitor, getType());
269             acceptChildren(visitor, variableDeclarationFragments);
270         }
271         visitor.endVisit(this);
272     }
273     
274     /**
275      * Returns the live ordered list of modifiers and annotations
276      * of this declaration (added in JLS3 API).
277      * <p>
278      * Note that the final modifier is the only meaningful modifier for local
279      * variable declarations.
280      * </p>
281      *
282      * @return the live list of modifiers and annotations
283      * (element type: <code>IExtendedModifier</code>)
284      * @exception UnsupportedOperationException if this operation is used in
285      * a JLS2 AST
286      * @since 3.1
287      */

288     public List JavaDoc modifiers() {
289         // more efficient than just calling unsupportedIn2() to check
290
if (this.modifiers == null) {
291             unsupportedIn2();
292         }
293         return this.modifiers;
294     }
295     
296     /**
297      * Returns the modifiers explicitly specified on this declaration.
298      * <p>
299      * In the JLS3 API, this method is a convenience method that
300      * computes these flags from <code>modifiers()</code>.
301      * </p>
302      *
303      * @return the bit-wise or of <code>Modifier</code> constants
304      * @see Modifier
305      */

306     public int getModifiers() {
307         // more efficient than checking getAST().API_LEVEL
308
if (this.modifiers == null) {
309             // JLS2 behavior - bona fide property
310
return this.modifierFlags;
311         } else {
312             // JLS3 behavior - convenient method
313
// performance could be improved by caching computed flags
314
// but this would require tracking changes to this.modifiers
315
int computedModifierFlags = Modifier.NONE;
316             for (Iterator JavaDoc it = modifiers().iterator(); it.hasNext(); ) {
317                 Object JavaDoc x = it.next();
318                 if (x instanceof Modifier) {
319                     computedModifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
320                 }
321             }
322             return computedModifierFlags;
323         }
324     }
325
326     /**
327      * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
328      * <p>
329      * Note that the final modifier is the only meaningful modifier for local
330      * variable declarations.
331      * </p>
332      *
333      * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
334      * @exception UnsupportedOperationException if this operation is used in
335      * an AST later than JLS2
336      * @see Modifier
337      * @deprecated In the JLS3 API, this method is replaced by
338      * {@link #modifiers()} which contains a list of a <code>Modifier</code> nodes.
339      */

340     public void setModifiers(int modifiers) {
341         internalSetModifiers(modifiers);
342     }
343     
344     /**
345      * Internal synonym for deprecated method. Used to avoid
346      * deprecation warnings.
347      * @since 3.1
348      */

349     /*package*/ final void internalSetModifiers(int pmodifiers) {
350         supportedOnlyIn2();
351         preValueChange(MODIFIERS_PROPERTY);
352         this.modifierFlags = pmodifiers;
353         postValueChange(MODIFIERS_PROPERTY);
354     }
355
356     /**
357      * Returns the base type declared in this variable declaration.
358      * <p>
359      * N.B. The individual child variable declaration fragments may specify
360      * additional array dimensions. So the type of the variable are not
361      * necessarily exactly this type.
362      * </p>
363      *
364      * @return the base type
365      */

366     public Type getType() {
367         if (this.baseType == null) {
368             // lazy init must be thread-safe for readers
369
synchronized (this) {
370                 if (this.baseType == null) {
371                     preLazyInit();
372                     this.baseType = this.ast.newPrimitiveType(PrimitiveType.INT);
373                     postLazyInit(this.baseType, TYPE_PROPERTY);
374                 }
375             }
376         }
377         return this.baseType;
378     }
379
380     /**
381      * Sets the base type declared in this variable declaration to the given
382      * type.
383      *
384      * @param type the new base type
385      * @exception IllegalArgumentException if:
386      * <ul>
387      * <li>the node belongs to a different AST</li>
388      * <li>the node already has a parent</li>
389      * </ul>
390      */

391     public void setType(Type type) {
392         if (type == null) {
393             throw new IllegalArgumentException JavaDoc();
394         }
395         ASTNode oldChild = this.baseType;
396         preReplaceChild(oldChild, type, TYPE_PROPERTY);
397         this.baseType = type;
398         postReplaceChild(oldChild, type, TYPE_PROPERTY);
399     }
400
401     /**
402      * Returns the live list of variable declaration fragments in this
403      * expression. Adding and removing nodes from this list affects this node
404      * dynamically. All nodes in this list must be
405      * <code>VariableDeclarationFragment</code>s; attempts to add any other
406      * type of node will trigger an exception.
407      *
408      * @return the live list of variable declaration fragments in this
409      * expression (element type: <code>VariableDeclarationFragment</code>)
410      */

411     public List JavaDoc fragments() {
412         return this.variableDeclarationFragments;
413     }
414
415     /* (omit javadoc for this method)
416      * Method declared on ASTNode.
417      */

418     int memSize() {
419         // treat Operator as free
420
return BASE_NODE_SIZE + 4 * 4;
421     }
422     
423     /* (omit javadoc for this method)
424      * Method declared on ASTNode.
425      */

426     int treeSize() {
427         return
428             memSize()
429             + (this.modifiers == null ? 0 : this.modifiers.listSize())
430             + (this.baseType == null ? 0 : getType().treeSize())
431             + this.variableDeclarationFragments.listSize();
432     }
433 }
434
435
Popular Tags