EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/VariableDeclaration.java
1/*******************************************************************************
2 * Copyright (c) 2000, 2019 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.List;
18
19/**
20 * Abstract base class of all AST node types that declare a single
21 * variable.
22 * <pre>
23 * VariableDeclaration:
24 *    SingleVariableDeclaration
25 *    VariableDeclarationFragment
26 * </pre>
27 *
28 * @see SingleVariableDeclaration
29 * @see VariableDeclarationFragment
30 * @since 2.0
31 */
32@SuppressWarnings({"rawtypes"})
33public abstract class VariableDeclaration extends ASTNode {
34
35    /**
36     * The variable name; lazily initialized; defaults to an unspecified,
37     * legal Java identifier.
38     */
39    SimpleName variableName = null;
40
41    /**
42     * The number of extra array dimensions that appear after the variable;
43     * defaults to 0. Not used in JLS8 and later.
44     *
45     * @since 2.1
46     * @deprecated In JLS8 and later, use {@link #extraDimensions} instead.
47     */
48    int extraArrayDimensions = 0;
49
50    /**
51     * List of extra dimensions this node has with optional annotations
52     * (element type: {@link Dimension}).
53     * Null before JLS8. Added in JLS8; defaults to an empty list
54     * (see constructor).
55     *
56     * @since 3.10
57     */
58    ASTNode.NodeList extraDimensions = null;
59
60    /**
61     * The initializer expression, or <code>null</code> if none;
62     * defaults to none.
63     */
64    Expression optionalInitializer = null;
65
66    /**
67     * Creates and returns a structural property descriptor for the
68     * "name" property declared on the given concrete node type (child type: {@link SimpleName}).
69     *
70     * @return the property descriptor
71     */
72    static final ChildPropertyDescriptor internalNamePropertyFactory(Class nodeClass) {
73        return new ChildPropertyDescriptor(nodeClass"name"SimpleName.classMANDATORYNO_CYCLE_RISK); //$NON-NLS-1$
74    }
75
76    /**
77     * Creates and returns a structural property descriptor for the
78     * "extraDimensions" property declared on the given concrete node type (type: {@link Integer}).
79     *
80     * @return the property descriptor
81     * @deprecated In JLS8 and later, use {@link #internalExtraDimensions2PropertyFactory(Class)} instead.
82     */
83    static final SimplePropertyDescriptor internalExtraDimensionsPropertyFactory(Class nodeClass) {
84        return     new SimplePropertyDescriptor(nodeClass"extraDimensions"int.classMANDATORY); //$NON-NLS-1$
85    }
86
87    /**
88     * Creates and returns a structural property descriptor for the
89     * "extraDimensions2" property declared on the given concrete node type (element type: {@link Dimension}).
90     *
91     * @return the property descriptor
92     */
93    static final ChildListPropertyDescriptor internalExtraDimensions2PropertyFactory(Class nodeClass) {
94        return     new ChildListPropertyDescriptor(nodeClass"extraDimensions2"Dimension.classCYCLE_RISK); //$NON-NLS-1$
95    }
96
97    /**
98     * Creates and returns a structural property descriptor for the
99     * "initializer" property declared on the given concrete node type (child type: {@link Expression}).
100     *
101     * @return the property descriptor
102     */
103    static final ChildPropertyDescriptor internalInitializerPropertyFactory(Class nodeClass) {
104        return     new ChildPropertyDescriptor(nodeClass"initializer"Expression.classOPTIONALCYCLE_RISK); //$NON-NLS-1$
105    }
106
107    /**
108     * Returns structural property descriptor for the "name" property
109     * of this node (child type: {@link SimpleName}).
110     *
111     * @return the property descriptor
112     * @since 3.1
113     */
114    abstract ChildPropertyDescriptor internalNameProperty();
115
116    /**
117     * Returns the structural property descriptor for the "name" property
118     * of this node (child type: {@link SimpleName}).
119     *
120     * @return the property descriptor
121     * @since 3.1
122     */
123    public final ChildPropertyDescriptor getNameProperty() {
124        return internalNameProperty();
125    }
126
127
128    /**
129     * Returns the structural property descriptor for the "extraDimensions" property
130     * of this node (type: {@link Integer}) (below JLS8 only).
131     *
132     * @return the property descriptor
133     * @since 3.1
134     * @deprecated In JLS8 and later, use {@link #internalExtraDimensions2Property()} instead.
135     */
136    abstract SimplePropertyDescriptor internalExtraDimensionsProperty();
137
138    /**
139     * Returns the structural property descriptor for the "extraDimensions" property
140     * of this node (type: {@link Integer}) (below JLS8 only).
141     *
142     * @return the property descriptor
143     * @since 3.1
144     * @deprecated In JLS8 and later, use {@link #getExtraDimensions2Property()} instead.
145     */
146    public final SimplePropertyDescriptor getExtraDimensionsProperty() {
147        return internalExtraDimensionsProperty();
148    }
149
150    /**
151     * Returns the structural property descriptor for the "extraDimensions" property
152     * of this node (element type: {@link Dimension}) (added in JLS8 API).
153     *
154     * @return the property descriptor
155     * @since 3.10
156     */
157    abstract ChildListPropertyDescriptor internalExtraDimensions2Property();
158
159    /**
160     * Returns the structural property descriptor for the "extraDimensions" property
161     * of this node (element type: {@link Dimension}) (added in JLS8 API).
162     *
163     * @return the property descriptor
164     * @since 3.10
165     */
166    public final ChildListPropertyDescriptor getExtraDimensions2Property() {
167        return internalExtraDimensions2Property();
168    }
169
170    /**
171     * Returns structural property descriptor for the "initializer" property
172     * of this node (child type: {@link Expression}).
173     *
174     * @return the property descriptor
175     * @since 3.1
176     */
177    abstract ChildPropertyDescriptor internalInitializerProperty();
178
179    /**
180     * Returns structural property descriptor for the "initializer" property
181     * of this node (child type: {@link Expression}).
182     *
183     * @return the property descriptor
184     * @since 3.1
185     */
186    public final ChildPropertyDescriptor getInitializerProperty() {
187        return internalInitializerProperty();
188    }
189
190    /**
191     * Creates a new AST node for a variable declaration owned by the given AST.
192     * <p>
193     * N.B. This constructor is package-private.
194     * </p>
195     *
196     * @param ast the AST that is to own this node
197     */
198    VariableDeclaration(AST ast) {
199        super(ast);
200        if (ast.apiLevel >= AST.JLS8_INTERNAL) {
201            this.extraDimensions = new ASTNode.NodeList(getExtraDimensions2Property());
202        }
203    }
204
205    /**
206     * Returns the name of the variable declared in this variable declaration.
207     *
208     * @return the variable name node
209     */
210    public SimpleName getName() {
211        if (this.variableName == null) {
212            // lazy init must be thread-safe for readers
213            synchronized (this) {
214                if (this.variableName == null) {
215                    preLazyInit();
216                    this.variableName = new SimpleName(this.ast);
217                    postLazyInit(this.variableNameinternalNameProperty());
218                }
219            }
220        }
221        return this.variableName;
222    }
223
224    /**
225     * Sets the name of the variable declared in this variable declaration
226     * to the given name.
227     *
228     * @param variableName the new variable name
229     * @exception IllegalArgumentException if:
230     * <ul>
231     * <li>the node belongs to a different AST</li>
232     * <li>the node already has a parent</li>
233     * </ul>
234     */
235    public void setName(SimpleName variableName) {
236        if (variableName == null) {
237            throw new IllegalArgumentException();
238        }
239        ChildPropertyDescriptor p = internalNameProperty();
240        ASTNode oldChild = this.variableName;
241        preReplaceChild(oldChildvariableNamep);
242        this.variableName = variableName;
243        postReplaceChild(oldChildvariableNamep);
244    }
245
246    /**
247     * Returns the number of extra array dimensions over and above the
248     * explicitly-specified type.
249     * <p>
250     * For example, <code>int x[][]</code> has a type of
251     * <code>int</code> and two extra array dimensions;
252     * <code>int[][] x</code> has a type of <code>int[][]</code>
253     * and zero extra array dimensions. The two constructs have different
254     * ASTs, even though there are really syntactic variants of the same
255     * variable declaration.
256     * </p>
257     * <p>
258     * In the JLS8 API, this method is a convenience method that
259     * counts {@link #extraDimensions()}.
260     * </p>
261     *
262     * @return the number of extra array dimensions
263     * @since 2.1
264     */
265    public int getExtraDimensions() {
266        // more efficient than checking getAST().API_LEVEL
267        if (this.extraDimensions == null) {
268            // JLS2,3,4 behavior - bona fide property
269            return this.extraArrayDimensions;
270        } else {
271            return this.extraDimensions.size();
272        }
273    }
274
275    /**
276     * Sets the number of extra array dimensions over and above the
277     * explicitly-specified type.
278     * <p>
279     * For example, <code>int x[][]</code> has a type of
280     * <code>int</code> and two extra array dimensions;
281     * <code>int[][] x</code> has a type of <code>int[][]</code>
282     * and zero extra array dimensions. The two constructs have different
283     * ASTs, even though there are really syntactic variants of the same
284     * variable declaration.
285     * </p>
286     *
287     * @param dimensions the number of array dimensions
288     * @exception IllegalArgumentException if the number of dimensions is
289     *    negative
290     * @exception UnsupportedOperationException if this operation is used in
291     * a JLS8 or later AST
292     * @deprecated In the JLS8 API, this method is replaced by
293     * {@link #extraDimensions()} which contains a list of {@link Dimension} nodes.
294     * @since 2.1
295     */
296    public void setExtraDimensions(int dimensions) {
297        internalSetExtraDimensions(dimensions);
298    }
299
300    /**
301     * Internal synonym for deprecated method. Used to avoid
302     * deprecation warnings.
303     * @since 3.10
304     */
305    final void internalSetExtraDimensions(int dimensions) {
306        // more efficient than just calling supportedOnlyIn2_3_4() to check
307        if (this.extraDimensions != null) {
308            supportedOnlyIn2_3_4();
309        }
310        if (dimensions < 0) {
311            throw new IllegalArgumentException();
312        }
313        SimplePropertyDescriptor p = internalExtraDimensionsProperty();
314        preValueChange(p);
315        this.extraArrayDimensions = dimensions;
316        postValueChange(p);
317    }
318
319    /**
320     * Returns the live ordered list of extra dimensions with optional annotations (added in JLS8 API).
321     *
322     * @return the live list of extra dimensions with optional annotations (element type: {@link Dimension})
323     * @exception UnsupportedOperationException if this operation is used below JLS8
324     * @since 3.10
325     */
326    public List extraDimensions() {
327        // more efficient than just calling unsupportedIn2_3_4() to check
328        if (this.extraDimensions == null) {
329            unsupportedIn2_3_4();
330        }
331        return this.extraDimensions;
332    }
333
334    /**
335     * Returns the initializer of this variable declaration, or
336     * <code>null</code> if there is none.
337     *
338     * @return the initializer expression node, or <code>null</code> if
339     *    there is none
340     */
341    public Expression getInitializer() {
342        return this.optionalInitializer;
343    }
344
345    /**
346     * Sets or clears the initializer of this variable declaration.
347     *
348     * @param initializer the initializer expression node, or <code>null</code>
349     *    if there is none
350     * @exception IllegalArgumentException if:
351     * <ul>
352     * <li>the node belongs to a different AST</li>
353     * <li>the node already has a parent</li>
354     * <li>a cycle in would be created</li>
355     * </ul>
356     */
357    public void setInitializer(Expression initializer) {
358        ChildPropertyDescriptor p = internalInitializerProperty();
359        ASTNode oldChild = this.optionalInitializer;
360        preReplaceChild(oldChildinitializerp);
361        this.optionalInitializer = initializer;
362        postReplaceChild(oldChildinitializerp);
363    }
364
365    /**
366     * Resolves and returns the binding for the variable declared in this
367     * variable declaration.
368     * <p>
369     * Note that bindings are generally unavailable unless requested when the
370     * AST is being built.
371     * </p>
372     *
373     * @return the binding, or <code>null</code> if the binding cannot be
374     *    resolved
375     */
376    public IVariableBinding resolveBinding() {
377        return this.ast.getBindingResolver().resolveVariable(this);
378    }
379}
380
MembersX
VariableDeclaration:internalNamePropertyFactory
VariableDeclaration:internalSetExtraDimensions:Block:p
VariableDeclaration:variableName
VariableDeclaration:getExtraDimensions2Property
VariableDeclaration:setInitializer:Block:oldChild
VariableDeclaration:setName:Block:oldChild
VariableDeclaration:getExtraDimensions
VariableDeclaration:getNameProperty
VariableDeclaration:internalExtraDimensionsProperty
VariableDeclaration:setExtraDimensions
VariableDeclaration:getInitializer
VariableDeclaration:resolveBinding
VariableDeclaration:extraArrayDimensions
VariableDeclaration:internalExtraDimensions2PropertyFactory
VariableDeclaration:internalExtraDimensions2Property
VariableDeclaration:internalNameProperty
VariableDeclaration:internalExtraDimensionsPropertyFactory
VariableDeclaration:getName
VariableDeclaration:getInitializerProperty
VariableDeclaration:setInitializer
VariableDeclaration:internalInitializerPropertyFactory
VariableDeclaration:setInitializer:Block:p
VariableDeclaration:optionalInitializer
VariableDeclaration:setName:Block:p
VariableDeclaration:getExtraDimensionsProperty
VariableDeclaration:extraDimensions
VariableDeclaration:internalSetExtraDimensions
VariableDeclaration:internalInitializerProperty
VariableDeclaration:VariableDeclaration
VariableDeclaration:setName
Members
X