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
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.ArrayList;
15 import java.util.List;
18 * Enhanced For statement AST node type (added in JLS3 API).
21 * EnhancedForStatement:
22 * <b>for</b> <b>(</b> FormalParameter <b>:</b> Expression <b>)</b>
25 * The FormalParameter is represented by a <code>SingleVariableDeclaration</code>
26 * (without an initializer).
29 * @noinstantiate This class is not intended to be instantiated by clients.
31 public class EnhancedForStatement extends Statement {
34 * The "parameter" structural property of this node type.
36 public static final ChildPropertyDescriptor PARAMETER_PROPERTY =
37 new ChildPropertyDescriptor(EnhancedForStatement.class, "parameter", SingleVariableDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
40 * The "expression" structural property of this node type.
42 public static final ChildPropertyDescriptor EXPRESSION_PROPERTY =
43 new ChildPropertyDescriptor(EnhancedForStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
46 * The "body" structural property of this node type.
48 public static final ChildPropertyDescriptor BODY_PROPERTY =
49 new ChildPropertyDescriptor(EnhancedForStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
52 * A list of property descriptors (element type:
53 * {@link StructuralPropertyDescriptor}),
54 * or null if uninitialized.
56 private static final List PROPERTY_DESCRIPTORS;
59 List properyList = new ArrayList(4);
60 createPropertyList(EnhancedForStatement.class, properyList);
61 addProperty(PARAMETER_PROPERTY, properyList);
62 addProperty(EXPRESSION_PROPERTY, properyList);
63 addProperty(BODY_PROPERTY, properyList);
64 PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
68 * Returns a list of structural property descriptors for this node type.
69 * Clients must not modify the result.
71 * @param apiLevel the API level; one of the
72 * <code>AST.JLS*</code> constants
74 * @return a list of property descriptors (element type:
75 * {@link StructuralPropertyDescriptor})
77 public static List propertyDescriptors(int apiLevel) {
78 return PROPERTY_DESCRIPTORS;
82 * The parameter; lazily initialized; defaults to a unspecified,
85 private SingleVariableDeclaration parameter = null;
88 * The expression; lazily initialized; defaults to a unspecified, but legal,
91 private Expression expression = null;
94 * The body statement; lazily initialized; defaults to an empty block
97 private Statement body = null;
100 * Creates a new AST node for an enchanced for statement owned by the
101 * given AST. By default, the parameter and expression are unspecified
102 * but legal subtrees, and the body is an empty block.
104 * @param ast the AST that is to own this node
106 EnhancedForStatement(AST ast) {
111 /* (omit javadoc for this method)
112 * Method declared on ASTNode.
114 final List internalStructuralPropertiesForType(int apiLevel) {
115 return propertyDescriptors(apiLevel);
118 /* (omit javadoc for this method)
119 * Method declared on ASTNode.
121 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
122 if (property == PARAMETER_PROPERTY) {
124 return getParameter();
126 setParameter((SingleVariableDeclaration) child);
130 if (property == EXPRESSION_PROPERTY) {
132 return getExpression();
134 setExpression((Expression) child);
138 if (property == BODY_PROPERTY) {
142 setBody((Statement) child);
146 // allow default implementation to flag the error
147 return super.internalGetSetChildProperty(property, get, child);
150 /* (omit javadoc for this method)
151 * Method declared on ASTNode.
153 final int getNodeType0() {
154 return ENHANCED_FOR_STATEMENT;
157 /* (omit javadoc for this method)
158 * Method declared on ASTNode.
160 ASTNode clone0(AST target) {
161 EnhancedForStatement result = new EnhancedForStatement(target);
162 result.setSourceRange(this.getStartPosition(), this.getLength());
163 result.copyLeadingComment(this);
164 result.setParameter((SingleVariableDeclaration) getParameter().clone(target));
165 result.setExpression((Expression) getExpression().clone(target));
167 (Statement) ASTNode.copySubtree(target, getBody()));
171 /* (omit javadoc for this method)
172 * Method declared on ASTNode.
174 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
175 // dispatch to correct overloaded match method
176 return matcher.match(this, other);
179 /* (omit javadoc for this method)
180 * Method declared on ASTNode.
182 void accept0(ASTVisitor visitor) {
183 boolean visitChildren = visitor.visit(this);
185 // visit children in normal left to right reading order
186 acceptChild(visitor, getParameter());
187 acceptChild(visitor, getExpression());
188 acceptChild(visitor, getBody());
190 visitor.endVisit(this);
194 * Returns the formal parameter in this enhanced for statement.
196 * @return the parameter
198 public SingleVariableDeclaration getParameter() {
199 if (this.parameter == null) {
200 // lazy init must be thread-safe for readers
201 synchronized (this) {
202 if (this.parameter == null) {
204 this.parameter = this.ast.newSingleVariableDeclaration();
205 postLazyInit(this.parameter, PARAMETER_PROPERTY);
209 return this.parameter;
213 * Sets the formal parameter in this enhanced for statement.
215 * @param parameter the new parameter
216 * @exception IllegalArgumentException if:
218 * <li>the node belongs to a different AST</li>
219 * <li>the node already has a parent</li>
222 public void setParameter(SingleVariableDeclaration parameter) {
223 if (parameter == null) {
224 throw new IllegalArgumentException();
226 ASTNode oldChild = this.parameter;
227 preReplaceChild(oldChild, parameter, PARAMETER_PROPERTY);
228 this.parameter = parameter;
229 postReplaceChild(oldChild, parameter, PARAMETER_PROPERTY);
233 * Returns the expression of this enhanced for statement.
235 * @return the expression node
237 public Expression getExpression() {
238 if (this.expression == null) {
239 // lazy init must be thread-safe for readers
240 synchronized (this) {
241 if (this.expression == null) {
243 this.expression = new SimpleName(this.ast);
244 postLazyInit(this.expression, EXPRESSION_PROPERTY);
248 return this.expression;
252 * Sets the expression of this enhanced for statement.
254 * @param expression the new expression node
255 * @exception IllegalArgumentException if:
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>
262 public void setExpression(Expression expression) {
263 if (expression == null) {
264 throw new IllegalArgumentException();
266 ASTNode oldChild = this.expression;
267 preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
268 this.expression = expression;
269 postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
273 * Returns the body of this enchanced for statement.
275 * @return the body statement node
277 public Statement getBody() {
278 if (this.body == null) {
279 // lazy init must be thread-safe for readers
280 synchronized (this) {
281 if (this.body == null) {
283 this.body = new Block(this.ast);
284 postLazyInit(this.body, BODY_PROPERTY);
292 * Sets the body of this enhanced for statement.
294 * @param statement the body statement node
295 * @exception IllegalArgumentException if:
297 * <li>the node belongs to a different AST</li>
298 * <li>the node already has a parent</li>
299 * <li>a cycle in would be created</li>
302 public void setBody(Statement statement) {
303 if (statement == null) {
304 throw new IllegalArgumentException();
306 ASTNode oldChild = this.body;
307 preReplaceChild(oldChild, statement, BODY_PROPERTY);
308 this.body = statement;
309 postReplaceChild(oldChild, statement, BODY_PROPERTY);
312 /* (omit javadoc for this method)
313 * Method declared on ASTNode.
316 return super.memSize() + 3 * 4;
319 /* (omit javadoc for this method)
320 * Method declared on ASTNode.
325 + (this.parameter == null ? 0 : getParameter().treeSize())
326 + (this.expression == null ? 0 : getExpression().treeSize())
327 + (this.body == null ? 0 : getBody().treeSize());