EclipseJDT Source Viewer

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