EclipseJDT Source Viewer

Home|eclipse_jdt/src/org/eclipse/jdt/core/dom/ForStatement.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.List;
19
20/**
21 * For statement AST node type.
22 *
23 * <pre>
24 * ForStatement:
25 *    <b>for</b> <b>(</b>
26 *             [ ForInit ]<b>;</b>
27 *             [ Expression ] <b>;</b>
28 *             [ ForUpdate ] <b>)</b>
29 *             Statement
30 * ForInit:
31 *         Expression { <b>,</b> Expression }
32 * ForUpdate:
33 *         Expression { <b>,</b> Expression }
34 * </pre>
35 * <p>
36 * Note: When variables are declared in the initializer
37 * of a for statement such as "<code>for (int a=1, b=2;;);</code>",
38 * they should be represented as a single
39 * <code>VariableDeclarationExpression</code>
40 * with two fragments, rather than being split up into a pair
41 * of expressions.
42 * </p>
43 *
44 * @since 2.0
45 * @noinstantiate This class is not intended to be instantiated by clients.
46 */
47@SuppressWarnings({"rawtypes""unchecked"})
48public class ForStatement extends Statement {
49
50    /**
51     * The "initializers" structural property of this node type (element type: {@link Expression}).
52     * @since 3.0
53     */
54    public static final ChildListPropertyDescriptor INITIALIZERS_PROPERTY =
55        new ChildListPropertyDescriptor(ForStatement.class"initializers"Expression.classCYCLE_RISK); //$NON-NLS-1$
56
57    /**
58     * The "expression" structural property of this node type (child type: {@link Expression}).
59     * @since 3.0
60     */
61    public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
62        new ChildPropertyDescriptor(ForStatement.class"expression"Expression.classOPTIONALCYCLE_RISK); //$NON-NLS-1$
63
64    /**
65     * The "updaters" structural property of this node type (element type: {@link Expression}).
66     * @since 3.0
67     */
68    public static final ChildListPropertyDescriptor UPDATERS_PROPERTY =
69        new ChildListPropertyDescriptor(ForStatement.class"updaters"Expression.classCYCLE_RISK); //$NON-NLS-1$
70
71    /**
72     * The "body" structural property of this node type (child type: {@link Statement}).
73     * @since 3.0
74     */
75    public static final ChildPropertyDescriptor BODY_PROPERTY =
76        new ChildPropertyDescriptor(ForStatement.class"body"Statement.classMANDATORYCYCLE_RISK); //$NON-NLS-1$
77
78    /**
79     * A list of property descriptors (element type:
80     * {@link StructuralPropertyDescriptor}),
81     * or null if uninitialized.
82     */
83    private static final List PROPERTY_DESCRIPTORS;
84
85    static {
86        List properyList = new ArrayList(5);
87        createPropertyList(ForStatement.classproperyList);
88        addProperty(INITIALIZERS_PROPERTYproperyList);
89        addProperty(EXPRESSION_PROPERTYproperyList);
90        addProperty(UPDATERS_PROPERTYproperyList);
91        addProperty(BODY_PROPERTYproperyList);
92        PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
93    }
94
95    /**
96     * Returns a list of structural property descriptors for this node type.
97     * Clients must not modify the result.
98     *
99     * @param apiLevel the API level; one of the
100     * <code>AST.JLS*</code> constants
101
102     * @return a list of property descriptors (element type:
103     * {@link StructuralPropertyDescriptor})
104     * @since 3.0
105     */
106    public static List propertyDescriptors(int apiLevel) {
107        return PROPERTY_DESCRIPTORS;
108    }
109
110    /**
111     * The list of initializer expressions (element type:
112     * {@link Expression}). Defaults to an empty list.
113     */
114    private ASTNode.NodeList initializers =
115        new ASTNode.NodeList(INITIALIZERS_PROPERTY);
116
117    /**
118     * The condition expression; <code>null</code> for none; defaults to none.
119     */
120    private Expression optionalConditionExpression = null;
121
122    /**
123     * The list of update expressions (element type:
124     * {@link Expression}). Defaults to an empty list.
125     */
126    private ASTNode.NodeList updaters =
127        new ASTNode.NodeList(UPDATERS_PROPERTY);
128
129    /**
130     * The body statement; lazily initialized; defaults to an empty block
131     * statement.
132     */
133    private Statement body = null;
134
135    /**
136     * Creates a new AST node for a for statement owned by the given AST.
137     * By default, there are no initializers, no condition expression,
138     * no updaters, and the body is an empty block.
139     *
140     * @param ast the AST that is to own this node
141     */
142    ForStatement(AST ast) {
143        super(ast);
144    }
145
146    @Override
147    final List internalStructuralPropertiesForType(int apiLevel) {
148        return propertyDescriptors(apiLevel);
149    }
150
151    @Override
152    final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor propertyboolean getASTNode child) {
153        if (property == EXPRESSION_PROPERTY) {
154            if (get) {
155                return getExpression();
156            } else {
157                setExpression((Expressionchild);
158                return null;
159            }
160        }
161        if (property == BODY_PROPERTY) {
162            if (get) {
163                return getBody();
164            } else {
165                setBody((Statementchild);
166                return null;
167            }
168        }
169        // allow default implementation to flag the error
170        return super.internalGetSetChildProperty(propertygetchild);
171    }
172
173    @Override
174    final List internalGetChildListProperty(ChildListPropertyDescriptor property) {
175        if (property == INITIALIZERS_PROPERTY) {
176            return initializers();
177        }
178        if (property == UPDATERS_PROPERTY) {
179            return updaters();
180        }
181        // allow default implementation to flag the error
182        return super.internalGetChildListProperty(property);
183    }
184
185    @Override
186    final int getNodeType0() {
187        return FOR_STATEMENT;
188    }
189
190    @Override
191    ASTNode clone0(AST target) {
192        ForStatement result = new ForStatement(target);
193        result.setSourceRange(getStartPosition(), getLength());
194        result.copyLeadingComment(this);
195        result.initializers().addAll(ASTNode.copySubtrees(targetinitializers()));
196        result.setExpression(
197            (ExpressionASTNode.copySubtree(targetgetExpression()));
198        result.updaters().addAll(ASTNode.copySubtrees(targetupdaters()));
199        result.setBody(
200            (StatementASTNode.copySubtree(targetgetBody()));
201        return result;
202    }
203
204    @Override
205    final boolean subtreeMatch0(ASTMatcher matcherObject other) {
206        // dispatch to correct overloaded match method
207        return matcher.match(this, other);
208    }
209
210    @Override
211    void accept0(ASTVisitor visitor) {
212        boolean visitChildren = visitor.visit(this);
213        if (visitChildren) {
214            // visit children in normal left to right reading order
215            acceptChildren(visitor, this.initializers);
216            acceptChild(visitorgetExpression());
217            acceptChildren(visitor, this.updaters);
218            acceptChild(visitorgetBody());
219        }
220        visitor.endVisit(this);
221    }
222
223    /**
224     * Returns the live ordered list of initializer expressions in this for
225     * statement.
226     * <p>
227     * The list should consist of either a list of so called statement
228     * expressions (JLS2, 14.8), or a single <code>VariableDeclarationExpression</code>.
229     * Otherwise, the for statement would have no Java source equivalent.
230     * </p>
231     *
232     * @return the live list of initializer expressions
233     *    (element type: {@link Expression})
234     */
235    public List initializers() {
236        return this.initializers;
237    }
238
239    /**
240     * Returns the condition expression of this for statement, or
241     * <code>null</code> if there is none.
242     *
243     * @return the condition expression node, or <code>null</code> if
244     *     there is none
245     */
246    public Expression getExpression() {
247        return this.optionalConditionExpression;
248    }
249
250    /**
251     * Sets or clears the condition expression of this return statement.
252     *
253     * @param expression the condition expression node, or <code>null</code>
254     *    if there is none
255     * @exception IllegalArgumentException if:
256     * <ul>
257     * <li>the node belongs to a different AST</li>
258     * <li>the node already has a parent</li>
259     * <li>a cycle in would be created</li>
260     * </ul>
261     */
262    public void setExpression(Expression expression) {
263        ASTNode oldChild = this.optionalConditionExpression;
264        preReplaceChild(oldChildexpressionEXPRESSION_PROPERTY);
265        this.optionalConditionExpression = expression;
266        postReplaceChild(oldChildexpressionEXPRESSION_PROPERTY);
267    }
268
269    /**
270     * Returns the live ordered list of update expressions in this for
271     * statement.
272     * <p>
273     * The list should consist of so called statement expressions. Otherwise,
274     * the for statement would have no Java source equivalent.
275     * </p>
276     *
277     * @return the live list of update expressions
278     *    (element type: {@link Expression})
279     */
280    public List updaters() {
281        return this.updaters;
282    }
283
284    /**
285     * Returns the body of this for statement.
286     *
287     * @return the body statement node
288     */
289    public Statement getBody() {
290        if (this.body == null) {
291            // lazy init must be thread-safe for readers
292            synchronized (this) {
293                if (this.body == null) {
294                    preLazyInit();
295                    this.body = new Block(this.ast);
296                    postLazyInit(this.bodyBODY_PROPERTY);
297                }
298            }
299        }
300        return this.body;
301    }
302
303    /**
304     * Sets the body of this for statement.
305     * <p>
306     * Special note: The Java language does not allow a local variable declaration
307     * to appear as the body of a for statement (they may only appear within a
308     * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
309     * as the body of a <code>ForStatement</code>. To get something that will
310     * compile, be sure to embed the <code>VariableDeclarationStatement</code>
311     * inside a <code>Block</code>.
312     * </p>
313     *
314     * @param statement the body statement node
315     * @exception IllegalArgumentException if:
316     * <ul>
317     * <li>the node belongs to a different AST</li>
318     * <li>the node already has a parent</li>
319     * <li>a cycle in would be created</li>
320     * </ul>
321     */
322    public void setBody(Statement statement) {
323        if (statement == null) {
324            throw new IllegalArgumentException();
325        }
326        ASTNode oldChild = this.body;
327        preReplaceChild(oldChildstatementBODY_PROPERTY);
328        this.body = statement;
329        postReplaceChild(oldChildstatementBODY_PROPERTY);
330    }
331
332    @Override
333    int memSize() {
334        return super.memSize() + 4 * 4;
335    }
336
337    @Override
338    int treeSize() {
339        return
340            memSize()
341            + this.initializers.listSize()
342            + this.updaters.listSize()
343            + (this.optionalConditionExpression == null ? 0 : getExpression().treeSize())
344            + (this.body == null ? 0 : getBody().treeSize());
345    }
346}
347
MembersX
ForStatement:Block:properyList
ForStatement:treeSize
ForStatement:clone0:Block:result
ForStatement:EXPRESSION_PROPERTY
ForStatement:getNodeType0
ForStatement:accept0:Block:visitChildren
ForStatement:ForStatement
ForStatement:internalGetSetChildProperty
ForStatement:internalGetChildListProperty
ForStatement:getExpression
ForStatement:BODY_PROPERTY
ForStatement:body
ForStatement:getBody
ForStatement:optionalConditionExpression
ForStatement:clone0
ForStatement:updaters
ForStatement:propertyDescriptors
ForStatement:INITIALIZERS_PROPERTY
ForStatement:internalStructuralPropertiesForType
ForStatement:setBody
ForStatement:initializers
ForStatement:setExpression:Block:oldChild
ForStatement:PROPERTY_DESCRIPTORS
ForStatement:memSize
ForStatement:subtreeMatch0
ForStatement:setExpression
ForStatement:UPDATERS_PROPERTY
ForStatement:setBody:Block:oldChild
ForStatement:accept0
Members
X