KickJava   Java API By Example, From Geeks To Geeks.

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


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  * Single variable declaration AST node type. Single variable
20  * declaration nodes are used in a limited number of places, including formal
21  * parameter lists and catch clauses. They are not used for field declarations
22  * and regular variable declaration statements.
23  * For JLS2:
24  * <pre>
25  * SingleVariableDeclaration:
26  * { Modifier } Type Identifier { <b>[</b><b>]</b> } [ <b>=</b> Expression ]
27  * </pre>
28  * For JLS3, the modifier flags were replaced by
29  * a list of modifier nodes (intermixed with annotations), and the variable arity
30  * indicator was added:
31  * <pre>
32  * SingleVariableDeclaration:
33  * { ExtendedModifier } Type [ <b>...</b> ] Identifier { <b>[</b><b>]</b> } [ <b>=</b> Expression ]
34  * </pre>
35  *
36  * @since 2.0
37  */

38 public class SingleVariableDeclaration extends VariableDeclaration {
39     
40     /**
41      * The "modifiers" structural property of this node type (JLS2 API only).
42      * @since 3.0
43      */

44     public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
45         new SimplePropertyDescriptor(SingleVariableDeclaration.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
46

47     /**
48      * The "modifiers" structural property of this node type (added in JLS3 API).
49      * @since 3.1
50      */

51     public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
52         new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
53

54     /**
55      * The "name" structural property of this node type.
56      * @since 3.0
57      */

58     public static final ChildPropertyDescriptor NAME_PROPERTY =
59         new ChildPropertyDescriptor(SingleVariableDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
60

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

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

68     /**
69      * The "varargs" structural property of this node type (added in JLS3 API).
70      * @since 3.1
71      */

72     public static final SimplePropertyDescriptor VARARGS_PROPERTY =
73         new SimplePropertyDescriptor(SingleVariableDeclaration.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$
74

75     /**
76      * The "extraDimensions" structural property of this node type.
77      * @since 3.0
78      */

79     public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY =
80         new SimplePropertyDescriptor(SingleVariableDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$
81

82     /**
83      * The "initializer" structural property of this node type.
84      * @since 3.0
85      */

86     public static final ChildPropertyDescriptor INITIALIZER_PROPERTY =
87         new ChildPropertyDescriptor(SingleVariableDeclaration.class, "initializer", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
88

89     /**
90      * A list of property descriptors (element type:
91      * {@link StructuralPropertyDescriptor}),
92      * or null if uninitialized.
93      * @since 3.0
94      */

95     private static final List JavaDoc PROPERTY_DESCRIPTORS_2_0;
96     
97     /**
98      * A list of property descriptors (element type:
99      * {@link StructuralPropertyDescriptor}),
100      * or null if uninitialized.
101      * @since 3.1
102      */

103     private static final List JavaDoc PROPERTY_DESCRIPTORS_3_0;
104     
105     static {
106         List JavaDoc propertyList = new ArrayList JavaDoc(6);
107         createPropertyList(SingleVariableDeclaration.class, propertyList);
108         addProperty(MODIFIERS_PROPERTY, propertyList);
109         addProperty(TYPE_PROPERTY, propertyList);
110         addProperty(NAME_PROPERTY, propertyList);
111         addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
112         addProperty(INITIALIZER_PROPERTY, propertyList);
113         PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
114         
115         propertyList = new ArrayList JavaDoc(7);
116         createPropertyList(SingleVariableDeclaration.class, propertyList);
117         addProperty(MODIFIERS2_PROPERTY, propertyList);
118         addProperty(TYPE_PROPERTY, propertyList);
119         addProperty(VARARGS_PROPERTY, propertyList);
120         addProperty(NAME_PROPERTY, propertyList);
121         addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
122         addProperty(INITIALIZER_PROPERTY, propertyList);
123         PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
124     }
125
126     /**
127      * Returns a list of structural property descriptors for this node type.
128      * Clients must not modify the result.
129      *
130      * @param apiLevel the API level; one of the
131      * <code>AST.JLS*</code> constants
132      * @return a list of property descriptors (element type:
133      * {@link StructuralPropertyDescriptor})
134      * @since 3.0
135      */

136     public static List JavaDoc propertyDescriptors(int apiLevel) {
137         if (apiLevel == AST.JLS2_INTERNAL) {
138             return PROPERTY_DESCRIPTORS_2_0;
139         } else {
140             return PROPERTY_DESCRIPTORS_3_0;
141         }
142     }
143             
144     /**
145      * The extended modifiers (element type: <code>IExtendedModifier</code>).
146      * Null in JLS2. Added in JLS3; defaults to an empty list
147      * (see constructor).
148      *
149      * @since 3.1
150      */

151     private ASTNode.NodeList modifiers = null;
152     
153     /**
154      * The modifiers; bit-wise or of Modifier flags.
155      * Defaults to none. Not used in 3.0.
156      */

157     private int modifierFlags = Modifier.NONE;
158     
159     /**
160      * The variable name; lazily initialized; defaults to a unspecified,
161      * legal Java identifier.
162      */

163     private SimpleName variableName = null;
164
165     /**
166      * The type; lazily initialized; defaults to a unspecified,
167      * legal type.
168      */

169     private Type type = null;
170
171     /**
172      * Indicates the last parameter of a variable arity method;
173      * defaults to false.
174      *
175      * @since 3.1
176      */

177     private boolean variableArity = false;
178
179     /**
180      * The number of extra array dimensions that appear after the variable;
181      * defaults to 0.
182      *
183      * @since 2.1
184      */

185     private int extraArrayDimensions = 0;
186
187     /**
188      * The initializer expression, or <code>null</code> if none;
189      * defaults to none.
190      */

191     private Expression optionalInitializer = null;
192
193     /**
194      * Creates a new AST node for a variable declaration owned by the given
195      * AST. By default, the variable declaration has: no modifiers, an
196      * unspecified (but legal) type, an unspecified (but legal) variable name,
197      * 0 dimensions after the variable; no initializer; not variable arity.
198      * <p>
199      * N.B. This constructor is package-private.
200      * </p>
201      *
202      * @param ast the AST that is to own this node
203      */

204     SingleVariableDeclaration(AST ast) {
205         super(ast);
206         if (ast.apiLevel >= AST.JLS3) {
207             this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
208         }
209     }
210
211     /* (omit javadoc for this method)
212      * Method declared on VariableDeclaration.
213      * @since 3.1
214      */

215     final SimplePropertyDescriptor internalExtraDimensionsProperty() {
216         return EXTRA_DIMENSIONS_PROPERTY;
217     }
218
219     /* (omit javadoc for this method)
220      * Method declared on VariableDeclaration.
221      * @since 3.1
222      */

223     final ChildPropertyDescriptor internalInitializerProperty() {
224         return INITIALIZER_PROPERTY;
225     }
226
227     /* (omit javadoc for this method)
228      * Method declared on VariableDeclaration.
229      * @since 3.1
230      */

231     final ChildPropertyDescriptor internalNameProperty() {
232         return NAME_PROPERTY;
233     }
234
235     /* (omit javadoc for this method)
236      * Method declared on ASTNode.
237      */

238     final List JavaDoc internalStructuralPropertiesForType(int apiLevel) {
239         return propertyDescriptors(apiLevel);
240     }
241     
242     /* (omit javadoc for this method)
243      * Method declared on ASTNode.
244      */

245     final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
246         if (property == MODIFIERS_PROPERTY) {
247             if (get) {
248                 return getModifiers();
249             } else {
250                 setModifiers(value);
251                 return 0;
252             }
253         }
254         if (property == EXTRA_DIMENSIONS_PROPERTY) {
255             if (get) {
256                 return getExtraDimensions();
257             } else {
258                 setExtraDimensions(value);
259                 return 0;
260             }
261         }
262         // allow default implementation to flag the error
263
return super.internalGetSetIntProperty(property, get, value);
264     }
265     
266     /* (omit javadoc for this method)
267      * Method declared on ASTNode.
268      */

269     final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
270         if (property == VARARGS_PROPERTY) {
271             if (get) {
272                 return isVarargs();
273             } else {
274                 setVarargs(value);
275                 return false;
276             }
277         }
278         // allow default implementation to flag the error
279
return super.internalGetSetBooleanProperty(property, get, value);
280     }
281     
282     /* (omit javadoc for this method)
283      * Method declared on ASTNode.
284      */

285     final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
286         if (property == NAME_PROPERTY) {
287             if (get) {
288                 return getName();
289             } else {
290                 setName((SimpleName) child);
291                 return null;
292             }
293         }
294         if (property == TYPE_PROPERTY) {
295             if (get) {
296                 return getType();
297             } else {
298                 setType((Type) child);
299                 return null;
300             }
301         }
302         if (property == INITIALIZER_PROPERTY) {
303             if (get) {
304                 return getInitializer();
305             } else {
306                 setInitializer((Expression) child);
307                 return null;
308             }
309         }
310         // allow default implementation to flag the error
311
return super.internalGetSetChildProperty(property, get, child);
312     }
313     
314     /* (omit javadoc for this method)
315      * Method declared on ASTNode.
316      */

317     final List JavaDoc internalGetChildListProperty(ChildListPropertyDescriptor property) {
318         if (property == MODIFIERS2_PROPERTY) {
319             return modifiers();
320         }
321         // allow default implementation to flag the error
322
return super.internalGetChildListProperty(property);
323     }
324     
325     /* (omit javadoc for this method)
326      * Method declared on ASTNode.
327      */

328     final int getNodeType0() {
329         return SINGLE_VARIABLE_DECLARATION;
330     }
331
332     /* (omit javadoc for this method)
333      * Method declared on ASTNode.
334      */

335     ASTNode clone0(AST target) {
336         SingleVariableDeclaration result = new SingleVariableDeclaration(target);
337         result.setSourceRange(this.getStartPosition(), this.getLength());
338         if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
339             result.setModifiers(getModifiers());
340         } else {
341             result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
342             result.setVarargs(isVarargs());
343         }
344         result.setType((Type) getType().clone(target));
345         result.setExtraDimensions(getExtraDimensions());
346         result.setName((SimpleName) getName().clone(target));
347         result.setInitializer(
348             (Expression) ASTNode.copySubtree(target, getInitializer()));
349         return result;
350     }
351
352     /* (omit javadoc for this method)
353      * Method declared on ASTNode.
354      */

355     final boolean subtreeMatch0(ASTMatcher matcher, Object JavaDoc other) {
356         // dispatch to correct overloaded match method
357
return matcher.match(this, other);
358     }
359     
360     /* (omit javadoc for this method)
361      * Method declared on ASTNode.
362      */

363     void accept0(ASTVisitor visitor) {
364         boolean visitChildren = visitor.visit(this);
365         if (visitChildren) {
366             // visit children in normal left to right reading order
367
if (this.ast.apiLevel >= AST.JLS3) {
368                 acceptChildren(visitor, this.modifiers);
369             }
370             acceptChild(visitor, getType());
371             acceptChild(visitor, getName());
372             acceptChild(visitor, getInitializer());
373         }
374         visitor.endVisit(this);
375     }
376     
377     /**
378      * Returns the live ordered list of modifiers and annotations
379      * of this declaration (added in JLS3 API).
380      * <p>
381      * Note that the final modifier is the only meaningful modifier for local
382      * variable and formal parameter declarations.
383      * </p>
384      *
385      * @return the live list of modifiers and annotations
386      * (element type: <code>IExtendedModifier</code>)
387      * @exception UnsupportedOperationException if this operation is used in
388      * a JLS2 AST
389      * @since 3.1
390      */

391     public List JavaDoc modifiers() {
392         // more efficient than just calling unsupportedIn2() to check
393
if (this.modifiers == null) {
394             unsupportedIn2();
395         }
396         return this.modifiers;
397     }
398     
399     /**
400      * Returns the modifiers explicitly specified on this declaration.
401      * <p>
402      * In the JLS3 API, this method is a convenience method that
403      * computes these flags from <code>modifiers()</code>.
404      * </p>
405      *
406      * @return the bit-wise or of <code>Modifier</code> constants
407      * @see Modifier
408      */

409     public int getModifiers() {
410         // more efficient than checking getAST().API_LEVEL
411
if (this.modifiers == null) {
412             // JLS2 behavior - bona fide property
413
return this.modifierFlags;
414         } else {
415             // JLS3 behavior - convenient method
416
// performance could be improved by caching computed flags
417
// but this would require tracking changes to this.modifiers
418
int computedModifierFlags = Modifier.NONE;
419             for (Iterator JavaDoc it = modifiers().iterator(); it.hasNext(); ) {
420                 Object JavaDoc x = it.next();
421                 if (x instanceof Modifier) {
422                     computedModifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
423                 }
424             }
425             return computedModifierFlags;
426         }
427     }
428
429     /**
430      * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
431      * <p>
432      * The following modifiers are meaningful for fields: public, private, protected,
433      * static, final, volatile, and transient. For local variable and formal
434      * parameter declarations, the only meaningful modifier is final.
435      * </p>
436      *
437      * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
438      * @exception UnsupportedOperationException if this operation is used in
439      * an AST later than JLS2
440      * @see Modifier
441      * @deprecated In the JLS3 API, this method is replaced by
442      * {@link #modifiers()} which contains a list of a <code>Modifier</code> nodes.
443      */

444     public void setModifiers(int modifiers) {
445         internalSetModifiers(modifiers);
446     }
447
448     /**
449      * Internal synonym for deprecated method. Used to avoid
450      * deprecation warnings.
451      * @since 3.1
452      */

453     /*package*/ final void internalSetModifiers(int pmodifiers) {
454         supportedOnlyIn2();
455         preValueChange(MODIFIERS_PROPERTY);
456         this.modifierFlags = pmodifiers;
457         postValueChange(MODIFIERS_PROPERTY);
458     }
459
460     /* (omit javadoc for this method)
461      * Method declared on VariableDeclaration.
462      */

463     public SimpleName getName() {
464         if (this.variableName == null) {
465             // lazy init must be thread-safe for readers
466
synchronized (this) {
467                 if (this.variableName == null) {
468                     preLazyInit();
469                     this.variableName = new SimpleName(this.ast);
470                     postLazyInit(this.variableName, NAME_PROPERTY);
471                 }
472             }
473         }
474         return this.variableName;
475     }
476         
477     /* (omit javadoc for this method)
478      * Method declared on VariableDeclaration.
479      */

480     public void setName(SimpleName variableName) {
481         if (variableName == null) {
482             throw new IllegalArgumentException JavaDoc();
483         }
484         ASTNode oldChild = this.variableName;
485         preReplaceChild(oldChild, variableName, NAME_PROPERTY);
486         this.variableName = variableName;
487         postReplaceChild(oldChild, variableName, NAME_PROPERTY);
488     }
489
490     /**
491      * Returns the type of the variable declared in this variable declaration,
492      * exclusive of any extra array dimensions.
493      *
494      * @return the type
495      */

496     public Type getType() {
497         if (this.type == null) {
498             // lazy init must be thread-safe for readers
499
synchronized (this) {
500                 if (this.type == null) {
501                     preLazyInit();
502                     this.type = this.ast.newPrimitiveType(PrimitiveType.INT);
503                     postLazyInit(this.type, TYPE_PROPERTY);
504                 }
505             }
506         }
507         return this.type;
508     }
509
510     /**
511      * Sets the type of the variable declared in this variable declaration to
512      * the given type, exclusive of any extra array dimensions.
513      *
514      * @param type the new type
515      * @exception IllegalArgumentException if:
516      * <ul>
517      * <li>the node belongs to a different AST</li>
518      * <li>the node already has a parent</li>
519      * </ul>
520      */

521     public void setType(Type type) {
522         if (type == null) {
523             throw new IllegalArgumentException JavaDoc();
524         }
525         ASTNode oldChild = this.type;
526         preReplaceChild(oldChild, type, TYPE_PROPERTY);
527         this.type = type;
528         postReplaceChild(oldChild, type, TYPE_PROPERTY);
529     }
530
531     /**
532      * Returns whether this declaration declares the last parameter of
533      * a variable arity method (added in JLS3 API).
534      * <p>
535      * Note that the binding for the type <code>Foo</code>in the vararg method
536      * declaration <code>void fun(Foo... args)</code> is always for the type as
537      * written; i.e., the type binding for <code>Foo</code>. However, if you
538      * navigate from the method declaration to its method binding to the
539      * type binding for its last parameter, the type binding for the vararg
540      * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
541      * the way vararg methods get compiled.
542      * </p>
543      *
544      * @return <code>true</code> if this is a variable arity parameter declaration,
545      * and <code>false</code> otherwise
546      * @exception UnsupportedOperationException if this operation is used in
547      * a JLS2 AST
548      * @since 3.1
549      */

550     public boolean isVarargs() {
551         // more efficient than just calling unsupportedIn2() to check
552
if (this.modifiers == null) {
553             unsupportedIn2();
554         }
555         return this.variableArity;
556     }
557     
558     /**
559      * Sets whether this declaration declares the last parameter of
560      * a variable arity method (added in JLS3 API).
561      *
562      * @param variableArity <code>true</code> if this is a variable arity
563      * parameter declaration, and <code>false</code> otherwise
564      * @since 3.1
565      */

566     public void setVarargs(boolean variableArity) {
567         // more efficient than just calling unsupportedIn2() to check
568
if (this.modifiers == null) {
569             unsupportedIn2();
570         }
571         preValueChange(VARARGS_PROPERTY);
572         this.variableArity = variableArity;
573         postValueChange(VARARGS_PROPERTY);
574     }
575
576     /* (omit javadoc for this method)
577      * Method declared on VariableDeclaration.
578      * @since 2.1
579      */

580     public int getExtraDimensions() {
581         return this.extraArrayDimensions;
582     }
583
584     /* (omit javadoc for this method)
585      * Method declared on VariableDeclaration.
586      * @since 2.1
587      */

588     public void setExtraDimensions(int dimensions) {
589         if (dimensions < 0) {
590             throw new IllegalArgumentException JavaDoc();
591         }
592         preValueChange(EXTRA_DIMENSIONS_PROPERTY);
593         this.extraArrayDimensions = dimensions;
594         postValueChange(EXTRA_DIMENSIONS_PROPERTY);
595     }
596
597     /* (omit javadoc for this method)
598      * Method declared on VariableDeclaration.
599      */

600     public Expression getInitializer() {
601         return this.optionalInitializer;
602     }
603     
604     /* (omit javadoc for this method)
605      * Method declared on VariableDeclaration.
606      */

607     public void setInitializer(Expression initializer) {
608         // a SingleVariableDeclaration may occur inside an Expression
609
// must check cycles
610
ASTNode oldChild = this.optionalInitializer;
611         preReplaceChild(oldChild, initializer,INITIALIZER_PROPERTY);
612         this.optionalInitializer = initializer;
613         postReplaceChild(oldChild, initializer,INITIALIZER_PROPERTY);
614     }
615
616     /* (omit javadoc for this method)
617      * Method declared on ASTNode.
618      */

619     int memSize() {
620         // treat Operator as free
621
return BASE_NODE_SIZE + 7 * 4;
622     }
623     
624     /* (omit javadoc for this method)
625      * Method declared on ASTNode.
626      */

627     int treeSize() {
628         return
629             memSize()
630             + (this.modifiers == null ? 0 : this.modifiers.listSize())
631             + (this.type == null ? 0 : getType().treeSize())
632             + (this.variableName == null ? 0 : getName().treeSize())
633             + (this.optionalInitializer == null ? 0 : getInitializer().treeSize());
634     }
635 }
636
Popular Tags