EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/VariableDeclarationStatement.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2013 IBM Corporation and others.
3 *
4 * This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License 2.0
6 * which accompanies this distribution, and is available at
7 * https://www.eclipse.org/legal/epl-2.0/
8 *
9 * SPDX-License-Identifier: EPL-2.0
10 *
11 * Contributors:
12 *     IBM Corporation - initial API and implementation
13 *******************************************************************************/
14
15package org.eclipse.jdt.core.dom;
16
17import java.util.ArrayList;
18import java.util.Iterator;
19import java.util.List;
20
21/**
22 * Local variable declaration statement AST node type.
23 * <p>
24 * This kind of node collects several variable declaration fragments
25 * (<code>VariableDeclarationFragment</code>) into a statement
26 * (<code>Statement</code>), all sharing the same modifiers and base type.
27 * </p>
28 * <pre>
29 * VariableDeclarationStatement:
30 *    { ExtendedModifier } Type VariableDeclarationFragment
31 *        { <b>,</b> VariableDeclarationFragment } <b>;</b>
32 * </pre>
33 * <p>
34 * Note: This type of node is a convenience of sorts.
35 * An equivalent way to represent the same statement is to use
36 * a <code>VariableDeclarationExpression</code>
37 * wrapped in an <code>ExpressionStatement</code>.
38 * </p>
39 *
40 * @since 2.0
41 * @noinstantiate This class is not intended to be instantiated by clients.
42 */
43@SuppressWarnings({"rawtypes""unchecked"})
44public class VariableDeclarationStatement extends Statement {
45
46    /**
47     * The "modifiers" structural property of this node type (type: {@link Integer}) (JLS2 API only).
48     * @since 3.0
49     * @deprecated In the JLS3 API, this property is replaced by {@link #MODIFIERS2_PROPERTY}.
50     */
51    public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
52        new SimplePropertyDescriptor(VariableDeclarationStatement.class"modifiers"int.classMANDATORY); //$NON-NLS-1$
53
54    /**
55     * The "modifiers" structural property of this node type (element type: {@link IExtendedModifier}) (added in JLS3 API).
56     * @since 3.1
57     */
58    public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
59        new ChildListPropertyDescriptor(VariableDeclarationStatement.class"modifiers"IExtendedModifier.classCYCLE_RISK); //$NON-NLS-1$
60
61    /**
62     * The "type" structural property of this node type (child type: {@link Type}).
63     * @since 3.0
64     */
65    public static final ChildPropertyDescriptor TYPE_PROPERTY =
66        new ChildPropertyDescriptor(VariableDeclarationStatement.class"type"Type.classMANDATORYNO_CYCLE_RISK); //$NON-NLS-1$
67
68    /**
69     * The "fragments" structural property of this node type (element type: {@link VariableDeclarationFragment}).
70     * @since 3.0
71     */
72    public static final ChildListPropertyDescriptor FRAGMENTS_PROPERTY =
73        new ChildListPropertyDescriptor(VariableDeclarationStatement.class"fragments"VariableDeclarationFragment.classCYCLE_RISK); //$NON-NLS-1$
74
75    /**
76     * A list of property descriptors (element type:
77     * {@link StructuralPropertyDescriptor}),
78     * or null if uninitialized.
79     * @since 3.0
80     */
81    private static final List PROPERTY_DESCRIPTORS_2_0;
82
83    /**
84     * A list of property descriptors (element type:
85     * {@link StructuralPropertyDescriptor}),
86     * or null if uninitialized.
87     * @since 3.1
88     */
89    private static final List PROPERTY_DESCRIPTORS_3_0;
90
91    static {
92        List propertyList = new ArrayList(4);
93        createPropertyList(VariableDeclarationStatement.classpropertyList);
94        addProperty(MODIFIERS_PROPERTYpropertyList);
95        addProperty(TYPE_PROPERTYpropertyList);
96        addProperty(FRAGMENTS_PROPERTYpropertyList);
97        PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
98
99        propertyList = new ArrayList(4);
100        createPropertyList(VariableDeclarationStatement.classpropertyList);
101        addProperty(MODIFIERS2_PROPERTYpropertyList);
102        addProperty(TYPE_PROPERTYpropertyList);
103        addProperty(FRAGMENTS_PROPERTYpropertyList);
104        PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
105    }
106
107    /**
108     * Returns a list of structural property descriptors for this node type.
109     * Clients must not modify the result.
110     *
111     * @param apiLevel the API level; one of the
112     * <code>AST.JLS*</code> constants
113
114     * @return a list of property descriptors (element type:
115     * {@link StructuralPropertyDescriptor})
116     * @since 3.0
117     */
118    public static List propertyDescriptors(int apiLevel) {
119        if (apiLevel == AST.JLS2_INTERNAL) {
120            return PROPERTY_DESCRIPTORS_2_0;
121        } else {
122            return PROPERTY_DESCRIPTORS_3_0;
123        }
124    }
125
126    /**
127     * The extended modifiers (element type: {@link IExtendedModifier}).
128     * Null in JLS2. Added in JLS3; defaults to an empty list
129     * (see constructor).
130     * @since 3.1
131     */
132    private ASTNode.NodeList modifiers = null;
133
134    /**
135     * The modifier flagss; bit-wise or of Modifier flags.
136     * Defaults to none. Not used in JLS3.
137     */
138    private int modifierFlags = Modifier.NONE;
139
140    /**
141     * The base type; lazily initialized; defaults to an unspecified,
142     * legal type.
143     */
144    private Type baseType = null;
145
146    /**
147     * The list of variable variable declaration fragments (element type:
148     * {@link VariableDeclarationFragment}).  Defaults to an empty list.
149     */
150    private ASTNode.NodeList variableDeclarationFragments =
151        new ASTNode.NodeList(FRAGMENTS_PROPERTY);
152
153    /**
154     * Creates a new unparented local variable declaration statement node owned
155     * by the given AST.  By default, the variable declaration has: no modifiers,
156     * an unspecified (but legal) type, and an empty list of variable
157     * declaration fragments (which is syntactically illegal).
158     * <p>
159     * N.B. This constructor is package-private.
160     * </p>
161     *
162     * @param ast the AST that is to own this node
163     */
164    VariableDeclarationStatement(AST ast) {
165        super(ast);
166        if (ast.apiLevel >= AST.JLS3_INTERNAL) {
167            this.modifiers = new ASTNode.NodeList(MODIFIERS2_PROPERTY);
168        }
169    }
170
171    @Override
172    final List internalStructuralPropertiesForType(int apiLevel) {
173        return propertyDescriptors(apiLevel);
174    }
175
176    @Override
177    final int internalGetSetIntProperty(SimplePropertyDescriptor propertyboolean getint value) {
178        if (property == MODIFIERS_PROPERTY) {
179            if (get) {
180                return getModifiers();
181            } else {
182                setModifiers(value);
183                return 0;
184            }
185        }
186        // allow default implementation to flag the error
187        return super.internalGetSetIntProperty(propertygetvalue);
188    }
189
190    @Override
191    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
192        if (property == TYPE_PROPERTY) {
193            if (get) {
194                return getType();
195            } else {
196                setType((Typechild);
197                return null;
198            }
199        }
200        // allow default implementation to flag the error
201        return super.internalGetSetChildProperty(propertygetchild);
202    }
203
204    @Override
205    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
206        if (property == MODIFIERS2_PROPERTY) {
207            return modifiers();
208        }
209        if (property == FRAGMENTS_PROPERTY) {
210            return fragments();
211        }
212        // allow default implementation to flag the error
213        return super.internalGetChildListProperty(property);
214    }
215
216    @Override
217    final int getNodeType0() {
218        return VARIABLE_DECLARATION_STATEMENT;
219    }
220
221    @Override
222    ASTNode clone0(AST target) {
223        VariableDeclarationStatement result =
224            new VariableDeclarationStatement(target);
225        result.setSourceRange(getStartPosition(), getLength());
226        result.copyLeadingComment(this);
227        if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
228            result.setModifiers(getModifiers());
229        }
230        if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
231            result.modifiers().addAll(ASTNode.copySubtrees(targetmodifiers()));
232        }
233        result.setType((TypegetType().clone(target));
234        result.fragments().addAll(
235            ASTNode.copySubtrees(targetfragments()));
236        return result;
237    }
238
239    @Override
240    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
241        // dispatch to correct overloaded match method
242        return matcher.match(this, other);
243    }
244
245    @Override
246    void accept0(ASTVisitor visitor) {
247        boolean visitChildren = visitor.visit(this);
248        if (visitChildren) {
249            // visit children in normal left to right reading order
250            if (this.ast.apiLevel >= AST.JLS3_INTERNAL) {
251                acceptChildren(visitor, this.modifiers);
252            }
253            acceptChild(visitorgetType());
254            acceptChildren(visitor, this.variableDeclarationFragments);
255        }
256        visitor.endVisit(this);
257    }
258
259    /**
260     * Returns the live ordered list of modifiers and annotations
261     * of this declaration (added in JLS3 API).
262     * <p>
263     * Note that the final modifier is the only meaningful modifier for local
264     * variable declarations.
265     * </p>
266     *
267     * @return the live list of modifiers and annotations
268     *    (element type: {@link IExtendedModifier})
269     * @exception UnsupportedOperationException if this operation is used in
270     * a JLS2 AST
271     * @since 3.1
272     */
273    public List modifiers() {
274        // more efficient than just calling unsupportedIn2() to check
275        if (this.modifiers == null) {
276            unsupportedIn2();
277        }
278        return this.modifiers;
279    }
280
281    /**
282     * Returns the modifiers explicitly specified on this declaration.
283     * <p>
284     * In the JLS3 API, this method is a convenience method that
285     * computes these flags from <code>modifiers()</code>.
286     * </p>
287     *
288     * @return the bit-wise or of <code>Modifier</code> constants
289     * @see Modifier
290     */
291    public int getModifiers() {
292        // more efficient than checking getAST().API_LEVEL
293        if (this.modifiers == null) {
294            // JLS2 behavior - bona fide property
295            return this.modifierFlags;
296        } else {
297            // JLS3 behavior - convenience method
298            // performance could be improved by caching computed flags
299            // but this would require tracking changes to this.modifiers
300            int computedModifierFlags = Modifier.NONE;
301            for (Iterator it = modifiers().iterator(); it.hasNext(); ) {
302                Object x = it.next();
303                if (x instanceof Modifier) {
304                    computedModifierFlags |= ((Modifierx).getKeyword().toFlagValue();
305                }
306            }
307            return computedModifierFlags;
308        }
309    }
310
311    /**
312     * Sets the modifiers explicitly specified on this declaration (JLS2 API only).
313     * <p>
314     * Note that the final modifier is the only meaningful modifier for local
315     * variable declarations.
316     * </p>
317     *
318     * @param modifiers the given modifiers (bit-wise or of <code>Modifier</code> constants)
319     * @exception UnsupportedOperationException if this operation is used in
320     * an AST later than JLS2
321     * @see Modifier
322     * @deprecated In the JLS3 API, this method is replaced by
323     * {@link  #modifiers()} which contains a list of a <code>Modifier</code> nodes.
324     */
325    public void setModifiers(int modifiers) {
326        internalSetModifiers(modifiers);
327    }
328
329    /**
330     * Internal synonym for deprecated method. Used to avoid
331     * deprecation warnings.
332     * @since 3.1
333     */
334    /*package*/ final void internalSetModifiers(int pmodifiers) {
335        supportedOnlyIn2();
336        preValueChange(MODIFIERS_PROPERTY);
337        this.modifierFlags = pmodifiers;
338        postValueChange(MODIFIERS_PROPERTY);
339    }
340
341    /**
342     * Returns the base type declared in this variable declaration statement.
343     * <p>
344     * N.B. The individual child variable declaration fragments may specify
345     * additional array dimensions. So the type of the variable are not
346     * necessarily exactly this type.
347     * </p>
348     *
349     * @return the base type
350     */
351    public Type getType() {
352        if (this.baseType == null) {
353            // lazy init must be thread-safe for readers
354            synchronized (this) {
355                if (this.baseType == null) {
356                    preLazyInit();
357                    this.baseType = this.ast.newPrimitiveType(PrimitiveType.INT);
358                    postLazyInit(this.baseTypeTYPE_PROPERTY);
359                }
360            }
361        }
362        return this.baseType;
363    }
364
365    /**
366     * Sets the base type declared in this variable declaration statement to
367     * the given type.
368     *
369     * @param type the new base type
370     * @exception IllegalArgumentException if:
371     * <ul>
372     * <li>the node belongs to a different AST</li>
373     * <li>the node already has a parent</li>
374     * </ul>
375     */
376    public void setType(Type type) {
377        if (type == null) {
378            throw new IllegalArgumentException();
379        }
380        ASTNode oldChild = this.baseType;
381        preReplaceChild(oldChildtypeTYPE_PROPERTY);
382        this.baseType = type;
383        postReplaceChild(oldChildtypeTYPE_PROPERTY);
384    }
385
386    /**
387     * Returns the live list of variable declaration fragments in this statement.
388     * Adding and removing nodes from this list affects this node dynamically.
389     * All nodes in this list must be <code>VariableDeclarationFragment</code>s;
390     * attempts to add any other type of node will trigger an
391     * exception.
392     *
393     * @return the live list of variable declaration fragments in this
394     *    statement (element type: {@link VariableDeclarationFragment})
395     */
396    public List fragments() {
397        return this.variableDeclarationFragments;
398    }
399
400    @Override
401    int memSize() {
402        return super.memSize() + 4 * 4;
403    }
404
405    @Override
406    int treeSize() {
407        return
408            memSize()
409            + (this.modifiers == null ? 0 : this.modifiers.listSize())
410            + (this.baseType == null ? 0 : getType().treeSize())
411            + this.variableDeclarationFragments.listSize();
412    }
413}
414
415
MembersX
VariableDeclarationStatement:modifiers
VariableDeclarationStatement:modifierFlags
VariableDeclarationStatement:accept0
VariableDeclarationStatement:accept0:Block:visitChildren
VariableDeclarationStatement:clone0:Block:result
VariableDeclarationStatement:setModifiers
VariableDeclarationStatement:Block:propertyList
VariableDeclarationStatement:TYPE_PROPERTY
VariableDeclarationStatement:treeSize
VariableDeclarationStatement:MODIFIERS2_PROPERTY
VariableDeclarationStatement:setType:Block:oldChild
VariableDeclarationStatement:internalSetModifiers
VariableDeclarationStatement:getType
VariableDeclarationStatement:FRAGMENTS_PROPERTY
VariableDeclarationStatement:baseType
VariableDeclarationStatement:variableDeclarationFragments
VariableDeclarationStatement:getNodeType0
VariableDeclarationStatement:fragments
VariableDeclarationStatement:internalGetSetChildProperty
VariableDeclarationStatement:VariableDeclarationStatement
VariableDeclarationStatement:PROPERTY_DESCRIPTORS_2_0
VariableDeclarationStatement:getModifiers
VariableDeclarationStatement:PROPERTY_DESCRIPTORS_3_0
VariableDeclarationStatement:propertyDescriptors
VariableDeclarationStatement:internalGetChildListProperty
VariableDeclarationStatement:clone0
VariableDeclarationStatement:memSize
VariableDeclarationStatement:getModifiers:Block:Block:computedModifierFlags
VariableDeclarationStatement:subtreeMatch0
VariableDeclarationStatement:getModifiers:Block:Block:Block:x
VariableDeclarationStatement:MODIFIERS_PROPERTY
VariableDeclarationStatement:internalGetSetIntProperty
VariableDeclarationStatement:setType
VariableDeclarationStatement:internalStructuralPropertiesForType
Members
X