001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.core.dom;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: /**
016: * Enhanced For statement AST node type (added in JLS3 API).
017: *
018: * <pre>
019: * EnhancedForStatement:
020: * <b>for</b> <b>(</b> FormalParameter <b>:</b> Expression <b>)</b>
021: * Statement
022: * </pre>
023: * The FormalParameter is represented by a <code>SingleVariableDeclaration</code>
024: * (without an initializer).
025: *
026: * @since 3.1
027: */
028: public class EnhancedForStatement extends Statement {
029:
030: /**
031: * The "parameter" structural property of this node type.
032: */
033: public static final ChildPropertyDescriptor PARAMETER_PROPERTY = new ChildPropertyDescriptor(
034: EnhancedForStatement.class,
035: "parameter", SingleVariableDeclaration.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
036:
037: /**
038: * The "expression" structural property of this node type.
039: */
040: public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = new ChildPropertyDescriptor(
041: EnhancedForStatement.class,
042: "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
043:
044: /**
045: * The "body" structural property of this node type.
046: */
047: public static final ChildPropertyDescriptor BODY_PROPERTY = new ChildPropertyDescriptor(
048: EnhancedForStatement.class,
049: "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
050:
051: /**
052: * A list of property descriptors (element type:
053: * {@link StructuralPropertyDescriptor}),
054: * or null if uninitialized.
055: */
056: private static final List PROPERTY_DESCRIPTORS;
057:
058: static {
059: List properyList = new ArrayList(4);
060: createPropertyList(EnhancedForStatement.class, properyList);
061: addProperty(PARAMETER_PROPERTY, properyList);
062: addProperty(EXPRESSION_PROPERTY, properyList);
063: addProperty(BODY_PROPERTY, properyList);
064: PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
065: }
066:
067: /**
068: * Returns a list of structural property descriptors for this node type.
069: * Clients must not modify the result.
070: *
071: * @param apiLevel the API level; one of the
072: * <code>AST.JLS*</code> constants
073:
074: * @return a list of property descriptors (element type:
075: * {@link StructuralPropertyDescriptor})
076: */
077: public static List propertyDescriptors(int apiLevel) {
078: return PROPERTY_DESCRIPTORS;
079: }
080:
081: /**
082: * The parameter; lazily initialized; defaults to a unspecified,
083: * legal node.
084: */
085: private SingleVariableDeclaration parameter = null;
086:
087: /**
088: * The expression; lazily initialized; defaults to a unspecified, but legal,
089: * expression.
090: */
091: private Expression expression = null;
092:
093: /**
094: * The body statement; lazily initialized; defaults to an empty block
095: * statement.
096: */
097: private Statement body = null;
098:
099: /**
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.
103: *
104: * @param ast the AST that is to own this node
105: */
106: EnhancedForStatement(AST ast) {
107: super (ast);
108: unsupportedIn2();
109: }
110:
111: /* (omit javadoc for this method)
112: * Method declared on ASTNode.
113: */
114: final List internalStructuralPropertiesForType(int apiLevel) {
115: return propertyDescriptors(apiLevel);
116: }
117:
118: /* (omit javadoc for this method)
119: * Method declared on ASTNode.
120: */
121: final ASTNode internalGetSetChildProperty(
122: ChildPropertyDescriptor property, boolean get, ASTNode child) {
123: if (property == PARAMETER_PROPERTY) {
124: if (get) {
125: return getParameter();
126: } else {
127: setParameter((SingleVariableDeclaration) child);
128: return null;
129: }
130: }
131: if (property == EXPRESSION_PROPERTY) {
132: if (get) {
133: return getExpression();
134: } else {
135: setExpression((Expression) child);
136: return null;
137: }
138: }
139: if (property == BODY_PROPERTY) {
140: if (get) {
141: return getBody();
142: } else {
143: setBody((Statement) child);
144: return null;
145: }
146: }
147: // allow default implementation to flag the error
148: return super .internalGetSetChildProperty(property, get, child);
149: }
150:
151: /* (omit javadoc for this method)
152: * Method declared on ASTNode.
153: */
154: final int getNodeType0() {
155: return ENHANCED_FOR_STATEMENT;
156: }
157:
158: /* (omit javadoc for this method)
159: * Method declared on ASTNode.
160: */
161: ASTNode clone0(AST target) {
162: EnhancedForStatement result = new EnhancedForStatement(target);
163: result
164: .setSourceRange(this .getStartPosition(), this
165: .getLength());
166: result.copyLeadingComment(this );
167: result.setParameter((SingleVariableDeclaration) getParameter()
168: .clone(target));
169: result
170: .setExpression((Expression) getExpression().clone(
171: target));
172: result.setBody((Statement) ASTNode.copySubtree(target,
173: getBody()));
174: return result;
175: }
176:
177: /* (omit javadoc for this method)
178: * Method declared on ASTNode.
179: */
180: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
181: // dispatch to correct overloaded match method
182: return matcher.match(this , other);
183: }
184:
185: /* (omit javadoc for this method)
186: * Method declared on ASTNode.
187: */
188: void accept0(ASTVisitor visitor) {
189: boolean visitChildren = visitor.visit(this );
190: if (visitChildren) {
191: // visit children in normal left to right reading order
192: acceptChild(visitor, getParameter());
193: acceptChild(visitor, getExpression());
194: acceptChild(visitor, getBody());
195: }
196: visitor.endVisit(this );
197: }
198:
199: /**
200: * Returns the formal parameter in this enhanced for statement.
201: *
202: * @return the parameter
203: */
204: public SingleVariableDeclaration getParameter() {
205: if (this .parameter == null) {
206: // lazy init must be thread-safe for readers
207: synchronized (this ) {
208: if (this .parameter == null) {
209: preLazyInit();
210: this .parameter = this .ast
211: .newSingleVariableDeclaration();
212: postLazyInit(this .parameter, PARAMETER_PROPERTY);
213: }
214: }
215: }
216: return this .parameter;
217: }
218:
219: /**
220: * Sets the formal parameter in this enhanced for statement.
221: *
222: * @param parameter the new parameter
223: * @exception IllegalArgumentException if:
224: * <ul>
225: * <li>the node belongs to a different AST</li>
226: * <li>the node already has a parent</li>
227: * </ul>
228: */
229: public void setParameter(SingleVariableDeclaration parameter) {
230: if (parameter == null) {
231: throw new IllegalArgumentException();
232: }
233: ASTNode oldChild = this .parameter;
234: preReplaceChild(oldChild, parameter, PARAMETER_PROPERTY);
235: this .parameter = parameter;
236: postReplaceChild(oldChild, parameter, PARAMETER_PROPERTY);
237: }
238:
239: /**
240: * Returns the expression of this enhanced for statement.
241: *
242: * @return the expression node
243: */
244: public Expression getExpression() {
245: if (this .expression == null) {
246: // lazy init must be thread-safe for readers
247: synchronized (this ) {
248: if (this .expression == null) {
249: preLazyInit();
250: this .expression = new SimpleName(this .ast);
251: postLazyInit(this .expression, EXPRESSION_PROPERTY);
252: }
253: }
254: }
255: return this .expression;
256: }
257:
258: /**
259: * Sets the expression of this enhanced for statement.
260: *
261: * @param expression the new expression node
262: * @exception IllegalArgumentException if:
263: * <ul>
264: * <li>the node belongs to a different AST</li>
265: * <li>the node already has a parent</li>
266: * <li>a cycle in would be created</li>
267: * </ul>
268: */
269: public void setExpression(Expression expression) {
270: if (expression == null) {
271: throw new IllegalArgumentException();
272: }
273: ASTNode oldChild = this .expression;
274: preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
275: this .expression = expression;
276: postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
277: }
278:
279: /**
280: * Returns the body of this enchanced for statement.
281: *
282: * @return the body statement node
283: */
284: public Statement getBody() {
285: if (this .body == null) {
286: // lazy init must be thread-safe for readers
287: synchronized (this ) {
288: if (this .body == null) {
289: preLazyInit();
290: this .body = new Block(this .ast);
291: postLazyInit(this .body, BODY_PROPERTY);
292: }
293: }
294: }
295: return this .body;
296: }
297:
298: /**
299: * Sets the body of this enhanced for statement.
300: *
301: * @param statement the body statement node
302: * @exception IllegalArgumentException if:
303: * <ul>
304: * <li>the node belongs to a different AST</li>
305: * <li>the node already has a parent</li>
306: * <li>a cycle in would be created</li>
307: * </ul>
308: */
309: public void setBody(Statement statement) {
310: if (statement == null) {
311: throw new IllegalArgumentException();
312: }
313: ASTNode oldChild = this .body;
314: preReplaceChild(oldChild, statement, BODY_PROPERTY);
315: this .body = statement;
316: postReplaceChild(oldChild, statement, BODY_PROPERTY);
317: }
318:
319: /* (omit javadoc for this method)
320: * Method declared on ASTNode.
321: */
322: int memSize() {
323: return super .memSize() + 3 * 4;
324: }
325:
326: /* (omit javadoc for this method)
327: * Method declared on ASTNode.
328: */
329: int treeSize() {
330: return memSize()
331: + (this .parameter == null ? 0 : getParameter()
332: .treeSize())
333: + (this .expression == null ? 0 : getExpression()
334: .treeSize())
335: + (this .body == null ? 0 : getBody().treeSize());
336: }
337: }
|