removed unused private methods.
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / SingleVariableDeclaration.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.Iterator;
16 import java.util.List;
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  * @noinstantiate This class is not intended to be instantiated by clients.
38  */
39 public class SingleVariableDeclaration extends VariableDeclaration {
40         
41         /**
42          * The "modifiers" structural property of this node type (JLS2 API only).
43          * @since 3.0
44          */
45         public static final SimplePropertyDescriptor MODIFIERS_PROPERTY = 
46                 new SimplePropertyDescriptor(SingleVariableDeclaration.class, "modifiers", int.class, MANDATORY); //$NON-NLS-1$
47         
48         /**
49          * The "modifiers" structural property of this node type (added in JLS3 API).
50          * @since 3.1
51          */
52         public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY = 
53                 new ChildListPropertyDescriptor(SingleVariableDeclaration.class, "modifiers", IExtendedModifier.class, CYCLE_RISK); //$NON-NLS-1$
54         
55         /**
56          * The "name" structural property of this node type.
57          * @since 3.0
58          */
59         public static final ChildPropertyDescriptor NAME_PROPERTY = 
60                 new ChildPropertyDescriptor(SingleVariableDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
61
62         /**
63          * The "type" structural property of this node type.
64          * @since 3.0
65          */
66         public static final ChildPropertyDescriptor TYPE_PROPERTY = 
67                 new ChildPropertyDescriptor(SingleVariableDeclaration.class, "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
68
69         /**
70          * The "varargs" structural property of this node type (added in JLS3 API).
71          * @since 3.1
72          */
73         public static final SimplePropertyDescriptor VARARGS_PROPERTY = 
74                 new SimplePropertyDescriptor(SingleVariableDeclaration.class, "varargs", boolean.class, MANDATORY); //$NON-NLS-1$
75         
76         /**
77          * The "extraDimensions" structural property of this node type.
78          * @since 3.0
79          */
80         public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY = 
81                 new SimplePropertyDescriptor(SingleVariableDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$
82         
83         /**
84          * The "initializer" structural property of this node type.
85          * @since 3.0
86          */
87         public static final ChildPropertyDescriptor INITIALIZER_PROPERTY = 
88                 new ChildPropertyDescriptor(SingleVariableDeclaration.class, "initializer", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
89
90         /**
91          * A list of property descriptors (element type: 
92          * {@link StructuralPropertyDescriptor}),
93          * or null if uninitialized.
94          * @since 3.0
95          */
96         private static final List PROPERTY_DESCRIPTORS_2_0;
97         
98         /**
99          * A list of property descriptors (element type: 
100          * {@link StructuralPropertyDescriptor}),
101          * or null if uninitialized.
102          * @since 3.1
103          */
104         private static final List PROPERTY_DESCRIPTORS_3_0;
105         
106         static {
107                 List propertyList = new ArrayList(6);
108                 createPropertyList(SingleVariableDeclaration.class, propertyList);
109                 addProperty(MODIFIERS_PROPERTY, propertyList);
110                 addProperty(TYPE_PROPERTY, propertyList);
111                 addProperty(NAME_PROPERTY, propertyList);
112                 addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
113                 addProperty(INITIALIZER_PROPERTY, propertyList);
114                 PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
115                 
116                 propertyList = new ArrayList(7);
117                 createPropertyList(SingleVariableDeclaration.class, propertyList);
118                 addProperty(MODIFIERS2_PROPERTY, propertyList);
119                 addProperty(TYPE_PROPERTY, propertyList);
120                 addProperty(VARARGS_PROPERTY, propertyList);
121                 addProperty(NAME_PROPERTY, propertyList);
122                 addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
123                 addProperty(INITIALIZER_PROPERTY, propertyList);
124                 PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
125         }
126
127         /**
128          * Returns a list of structural property descriptors for this node type.
129          * Clients must not modify the result.
130          * 
131          * @param apiLevel the API level; one of the
132          * <code>AST.JLS*</code> constants
133          * @return a list of property descriptors (element type: 
134          * {@link StructuralPropertyDescriptor})
135          * @since 3.0
136          */
137         public static List propertyDescriptors(int apiLevel) {
138                 if (apiLevel == AST.JLS2_INTERNAL) {
139                         return PROPERTY_DESCRIPTORS_2_0;
140                 } else {
141                         return PROPERTY_DESCRIPTORS_3_0;
142                 }
143         }
144                         
145         /**
146          * The extended modifiers (element type: <code>IExtendedModifier</code>). 
147          * Null in JLS2. Added in JLS3; defaults to an empty list
148          * (see constructor).
149          * 
150          * @since 3.1
151          */
152         private ASTNode.NodeList modifiers = null;
153         
154         /**
155          * The modifiers; bit-wise or of Modifier flags.
156          * Defaults to none. Not used in 3.0.
157          */
158         private int modifierFlags = Modifier.NONE;
159         
160         /**
161          * The variable name; lazily initialized; defaults to a unspecified,
162          * legal Java identifier.
163          */
164         private SimpleName variableName = null;
165
166         /**
167          * The type; lazily initialized; defaults to a unspecified,
168          * legal type.
169          */
170         private Type type = null;
171
172         /**
173          * Indicates the last parameter of a variable arity method;
174          * defaults to false.
175          * 
176          * @since 3.1
177          */
178         private boolean variableArity = false;
179
180         /**
181          * The number of extra array dimensions that appear after the variable;
182          * defaults to 0.
183          * 
184          * @since 2.1
185          */
186         private int extraArrayDimensions = 0;
187
188         /**
189          * The initializer expression, or <code>null</code> if none;
190          * defaults to none.
191          */
192         private Expression optionalInitializer = null;
193
194         /**
195          * Creates a new AST node for a variable declaration owned by the given 
196          * AST. By default, the variable declaration has: no modifiers, an 
197          * unspecified (but legal) type, an unspecified (but legal) variable name, 
198          * 0 dimensions after the variable; no initializer; not variable arity.
199          * <p>
200          * N.B. This constructor is package-private.
201          * </p>
202          * 
203          * @param ast the AST that is to own this node
204          */
205         SingleVariableDeclaration(AST ast) {
206                 super(ast);
207                 if (ast.apiLevel >= AST.JLS3) {
208                         this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
209                 }
210         }
211
212         /* (omit javadoc for this method)
213          * Method declared on VariableDeclaration.
214          * @since 3.1
215          */
216         final SimplePropertyDescriptor internalExtraDimensionsProperty() {
217                 return EXTRA_DIMENSIONS_PROPERTY;
218         }
219
220         /* (omit javadoc for this method)
221          * Method declared on VariableDeclaration.
222          * @since 3.1
223          */
224         final ChildPropertyDescriptor internalInitializerProperty() {
225                 return INITIALIZER_PROPERTY;
226         }
227
228         /* (omit javadoc for this method)
229          * Method declared on VariableDeclaration.
230          * @since 3.1
231          */
232         final ChildPropertyDescriptor internalNameProperty() {
233                 return NAME_PROPERTY;
234         }
235
236         /* (omit javadoc for this method)
237          * Method declared on ASTNode.
238          */
239         final List internalStructuralPropertiesForType(int apiLevel) {
240                 return propertyDescriptors(apiLevel);
241         }
242         
243         /* (omit javadoc for this method)
244          * Method declared on ASTNode.
245          */
246         final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
247                 if (property == MODIFIERS_PROPERTY) {
248                         if (get) {
249                                 return getModifiers();
250                         } else {
251                                 setModifiers(value);
252                                 return 0;
253                         }
254                 }
255                 if (property == EXTRA_DIMENSIONS_PROPERTY) {
256                         if (get) {
257                                 return getExtraDimensions();
258                         } else {
259                                 setExtraDimensions(value);
260                                 return 0;
261                         }
262                 }
263                 // allow default implementation to flag the error
264                 return super.internalGetSetIntProperty(property, get, value);
265         }
266         
267         /* (omit javadoc for this method)
268          * Method declared on ASTNode.
269          */
270         final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
271                 if (property == VARARGS_PROPERTY) {
272                         if (get) {
273                                 return isVarargs();
274                         } else {
275                                 setVarargs(value);
276                                 return false;
277                         }
278                 }
279                 // allow default implementation to flag the error
280                 return super.internalGetSetBooleanProperty(property, get, value);
281         }
282         
283         /* (omit javadoc for this method)
284          * Method declared on ASTNode.
285          */
286         final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
287                 if (property == NAME_PROPERTY) {
288                         if (get) {
289                                 return getName();
290                         } else {
291                                 setName((SimpleName) child);
292                                 return null;
293                         }
294                 }
295                 if (property == TYPE_PROPERTY) {
296                         if (get) {
297                                 return getType();
298                         } else {
299                                 setType((Type) child);
300                                 return null;
301                         }
302                 }
303                 if (property == INITIALIZER_PROPERTY) {
304                         if (get) {
305                                 return getInitializer();
306                         } else {
307                                 setInitializer((Expression) child);
308                                 return null;
309                         }
310                 }
311                 // allow default implementation to flag the error
312                 return super.internalGetSetChildProperty(property, get, child);
313         }
314         
315         /* (omit javadoc for this method)
316          * Method declared on ASTNode.
317          */
318         final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
319                 if (property == MODIFIERS2_PROPERTY) {
320                         return modifiers();
321                 }
322                 // allow default implementation to flag the error
323                 return super.internalGetChildListProperty(property);
324         }
325         
326         /* (omit javadoc for this method)
327          * Method declared on ASTNode.
328          */
329         final int getNodeType0() {
330                 return SINGLE_VARIABLE_DECLARATION;
331         }
332
333         /* (omit javadoc for this method)
334          * Method declared on ASTNode.
335          */
336         ASTNode clone0(AST target) {
337                 SingleVariableDeclaration result = new SingleVariableDeclaration(target);
338                 result.setSourceRange(this.getStartPosition(), this.getLength());
339                 if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
340                         result.setModifiers(getModifiers());
341                 } else {
342                         result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
343                         result.setVarargs(isVarargs());
344                 }
345                 result.setType((Type) getType().clone(target));
346                 result.setExtraDimensions(getExtraDimensions());
347                 result.setName((SimpleName) getName().clone(target));
348                 result.setInitializer(
349                         (Expression) ASTNode.copySubtree(target, getInitializer()));
350                 return result;
351         }
352
353         /* (omit javadoc for this method)
354          * Method declared on ASTNode.
355          */
356         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
357                 // dispatch to correct overloaded match method
358                 return matcher.match(this, other);
359         }
360         
361         /* (omit javadoc for this method)
362          * Method declared on ASTNode.
363          */
364         void accept0(ASTVisitor visitor) {
365                 boolean visitChildren = visitor.visit(this);
366                 if (visitChildren) {
367                         // visit children in normal left to right reading order
368                         if (this.ast.apiLevel >= AST.JLS3) {
369                                 acceptChildren(visitor, this.modifiers);
370                         }
371                         acceptChild(visitor, getType());
372                         acceptChild(visitor, getName());
373                         acceptChild(visitor, getInitializer());
374                 }
375                 visitor.endVisit(this);
376         }
377         
378         /**
379          * Returns the live ordered list of modifiers and annotations
380          * of this declaration (added in JLS3 API).
381          * <p>
382          * Note that the final modifier is the only meaningful modifier for local
383          * variable and formal parameter declarations.
384          * </p>
385          * 
386          * @return the live list of modifiers and annotations
387          *    (element type: <code>IExtendedModifier</code>)
388          * @exception UnsupportedOperationException if this operation is used in
389          * a JLS2 AST
390          * @since 3.1
391          */ 
392         public List modifiers() {
393                 // more efficient than just calling unsupportedIn2() to check
394                 if (this.modifiers == null) {
395                         unsupportedIn2();
396                 }
397                 return this.modifiers;
398         }
399         
400         /**
401          * Returns the modifiers explicitly specified on this declaration.
402          * <p>
403          * In the JLS3 API, this method is a convenience method that
404          * computes these flags from <code>modifiers()</code>.
405          * </p>
406          * 
407          * @return the bit-wise or of <code>Modifier</code> constants
408          * @see Modifier
409          */ 
410         public int getModifiers() {
411                 // more efficient than checking getAST().API_LEVEL
412                 if (this.modifiers == null) {
413                         // JLS2 behavior - bona fide property
414                         return this.modifierFlags;
415                 } else {
416                         // JLS3 behavior - convenient method
417                         // performance could be improved by caching computed flags
418                         // but this would require tracking changes to this.modifiers
419                         int computedModifierFlags = Modifier.NONE;
420                         for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
421                                 Object x = it.next();
422                                 if (x instanceof Modifier) {
423                                         computedModifierFlags |= ((Modifier) x).getKeyword().toFlagValue();
424                                 }
425                         }
426                         return computedModifierFlags;
427                 }
428         }
429
430         /**
431          * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
432          * <p>
433          * The following modifiers are meaningful for fields: public, private, protected,
434          * static, final, volatile, and transient. For local variable and formal
435          * parameter declarations, the only meaningful modifier is final.
436          * </p>
437          * 
438          * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
439          * @exception UnsupportedOperationException if this operation is used in
440          * an AST later than JLS2
441          * @see Modifier
442          * @deprecated In the JLS3 API, this method is replaced by 
443          * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
444          */ 
445         public void setModifiers(int modifiers) {
446                 internalSetModifiers(modifiers);
447         }
448
449         /**
450          * Internal synonym for deprecated method. Used to avoid
451          * deprecation warnings.
452          * @since 3.1
453          */
454         /*package*/ final void internalSetModifiers(int pmodifiers) {
455             supportedOnlyIn2();
456                 preValueChange(MODIFIERS_PROPERTY);
457                 this.modifierFlags = pmodifiers;
458                 postValueChange(MODIFIERS_PROPERTY);
459         }
460
461         /* (omit javadoc for this method)
462          * Method declared on VariableDeclaration.
463          */ 
464         public SimpleName getName() {
465                 if (this.variableName == null) {
466                         // lazy init must be thread-safe for readers
467                         synchronized (this) {
468                                 if (this.variableName == null) {
469                                         preLazyInit();
470                                         this.variableName = new SimpleName(this.ast);
471                                         postLazyInit(this.variableName, NAME_PROPERTY);
472                                 }
473                         }
474                 }
475                 return this.variableName;
476         }
477                 
478         /* (omit javadoc for this method)
479          * Method declared on VariableDeclaration.
480          */ 
481         public void setName(SimpleName variableName) {
482                 if (variableName == null) {
483                         throw new IllegalArgumentException();
484                 }
485                 ASTNode oldChild = this.variableName;
486                 preReplaceChild(oldChild, variableName, NAME_PROPERTY);
487                 this.variableName = variableName;
488                 postReplaceChild(oldChild, variableName, NAME_PROPERTY);
489         }
490
491         /**
492          * Returns the type of the variable declared in this variable declaration,
493          * exclusive of any extra array dimensions.
494          * 
495          * @return the type
496          */ 
497         public Type getType() {
498                 if (this.type == null) {
499                         // lazy init must be thread-safe for readers
500                         synchronized (this) {
501                                 if (this.type == null) {
502                                         preLazyInit();
503                                         this.type = this.ast.newPrimitiveType(PrimitiveType.INT);
504                                         postLazyInit(this.type, TYPE_PROPERTY);
505                                 }
506                         }
507                 }
508                 return this.type;
509         }
510
511         /**
512          * Sets the type of the variable declared in this variable declaration to 
513          * the given type, exclusive of any extra array dimensions.
514          * 
515          * @param type the new type
516          * @exception IllegalArgumentException if:
517          * <ul>
518          * <li>the node belongs to a different AST</li>
519          * <li>the node already has a parent</li>
520          * </ul>
521          */ 
522         public void setType(Type type) {
523                 if (type == null) {
524                         throw new IllegalArgumentException();
525                 }
526                 ASTNode oldChild = this.type;
527                 preReplaceChild(oldChild, type, TYPE_PROPERTY);
528                 this.type = type;
529                 postReplaceChild(oldChild, type, TYPE_PROPERTY);
530         }
531
532         /**
533          * Returns whether this declaration declares the last parameter of
534          * a variable arity method (added in JLS3 API).
535          * <p>
536          * Note that the binding for the type <code>Foo</code>in the vararg method
537          * declaration <code>void fun(Foo... args)</code> is always for the type as 
538          * written; i.e., the type binding for <code>Foo</code>. However, if you
539          * navigate from the method declaration to its method binding to the
540          * type binding for its last parameter, the type binding for the vararg
541          * parameter is always an array type (i.e., <code>Foo[]</code>) reflecting
542          * the way vararg methods get compiled.
543          * </p>
544          * 
545          * @return <code>true</code> if this is a variable arity parameter declaration,
546          *    and <code>false</code> otherwise
547          * @exception UnsupportedOperationException if this operation is used in
548          * a JLS2 AST
549          * @since 3.1
550          */ 
551         public boolean isVarargs() {
552                 // more efficient than just calling unsupportedIn2() to check
553                 if (this.modifiers == null) {
554                         unsupportedIn2();
555                 }
556                 return this.variableArity;
557         }
558         
559         /**
560          * Sets whether this declaration declares the last parameter of
561          * a variable arity method (added in JLS3 API).
562          * 
563          * @param variableArity <code>true</code> if this is a variable arity
564          *    parameter declaration, and <code>false</code> otherwise
565          * @since 3.1
566          */ 
567         public void setVarargs(boolean variableArity) {
568                 // more efficient than just calling unsupportedIn2() to check
569                 if (this.modifiers == null) {
570                         unsupportedIn2();
571                 }
572                 preValueChange(VARARGS_PROPERTY);
573                 this.variableArity = variableArity;
574                 postValueChange(VARARGS_PROPERTY);
575         }
576
577         /* (omit javadoc for this method)
578          * Method declared on VariableDeclaration.
579          * @since 2.1
580          */ 
581         public int getExtraDimensions() {
582                 return this.extraArrayDimensions;
583         }
584
585         /* (omit javadoc for this method)
586          * Method declared on VariableDeclaration.
587          * @since 2.1
588          */ 
589         public void setExtraDimensions(int dimensions) {
590                 if (dimensions < 0) {
591                         throw new IllegalArgumentException();
592                 }
593                 preValueChange(EXTRA_DIMENSIONS_PROPERTY);
594                 this.extraArrayDimensions = dimensions;
595                 postValueChange(EXTRA_DIMENSIONS_PROPERTY);
596         }
597
598         /* (omit javadoc for this method)
599          * Method declared on VariableDeclaration.
600          */ 
601         public Expression getInitializer() {
602                 return this.optionalInitializer;
603         }
604         
605         /* (omit javadoc for this method)
606          * Method declared on VariableDeclaration.
607          */ 
608         public void setInitializer(Expression initializer) {
609                 // a SingleVariableDeclaration may occur inside an Expression 
610                 // must check cycles
611                 ASTNode oldChild = this.optionalInitializer;
612                 preReplaceChild(oldChild, initializer,INITIALIZER_PROPERTY);
613                 this.optionalInitializer = initializer;
614                 postReplaceChild(oldChild, initializer,INITIALIZER_PROPERTY);
615         }
616
617         /* (omit javadoc for this method)
618          * Method declared on ASTNode.
619          */
620         int memSize() {
621                 // treat Operator as free
622                 return BASE_NODE_SIZE + 7 * 4;
623         }
624         
625         /* (omit javadoc for this method)
626          * Method declared on ASTNode.
627          */
628         int treeSize() {
629                 return 
630                         memSize()
631                         + (this.modifiers == null ? 0 : this.modifiers.listSize())
632                         + (this.type == null ? 0 : getType().treeSize())
633                         + (this.variableName == null ? 0 : getName().treeSize())
634                         + (this.optionalInitializer == null ? 0 : getInitializer().treeSize());
635         }
636 }