001: /*******************************************************************************
002: * Copyright (c) 2000, 2006 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: * While statement AST node type.
017: *
018: * <pre>
019: * WhileStatement:
020: * <b>while</b> <b>(</b> Expression <b>)</b> Statement
021: * </pre>
022: *
023: * @since 2.0
024: */
025: public class WhileStatement extends Statement {
026:
027: /**
028: * The "expression" structural property of this node type.
029: * @since 3.0
030: */
031: public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = new ChildPropertyDescriptor(
032: WhileStatement.class,
033: "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
034:
035: /**
036: * The "body" structural property of this node type.
037: * @since 3.0
038: */
039: public static final ChildPropertyDescriptor BODY_PROPERTY = new ChildPropertyDescriptor(
040: WhileStatement.class,
041: "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
042:
043: /**
044: * A list of property descriptors (element type:
045: * {@link StructuralPropertyDescriptor}),
046: * or null if uninitialized.
047: */
048: private static final List PROPERTY_DESCRIPTORS;
049:
050: static {
051: List propertyList = new ArrayList(3);
052: createPropertyList(WhileStatement.class, propertyList);
053: addProperty(EXPRESSION_PROPERTY, propertyList);
054: addProperty(BODY_PROPERTY, propertyList);
055: PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
056: }
057:
058: /**
059: * Returns a list of structural property descriptors for this node type.
060: * Clients must not modify the result.
061: *
062: * @param apiLevel the API level; one of the
063: * <code>AST.JLS*</code> constants
064:
065: * @return a list of property descriptors (element type:
066: * {@link StructuralPropertyDescriptor})
067: * @since 3.0
068: */
069: public static List propertyDescriptors(int apiLevel) {
070: return PROPERTY_DESCRIPTORS;
071: }
072:
073: /**
074: * The expression; lazily initialized; defaults to an unspecified, but
075: * legal, expression.
076: */
077: private Expression expression = null;
078:
079: /**
080: * The body statement; lazily initialized; defaults to an empty block
081: * statement.
082: */
083: private Statement body = null;
084:
085: /**
086: * Creates a new unparented while statement node owned by the given
087: * AST. By default, the expresssion is unspecified, but legal, and
088: * the body statement is an empty block.
089: * <p>
090: * N.B. This constructor is package-private.
091: * </p>
092: *
093: * @param ast the AST that is to own this node
094: */
095: WhileStatement(AST ast) {
096: super (ast);
097: }
098:
099: /* (omit javadoc for this method)
100: * Method declared on ASTNode.
101: */
102: final List internalStructuralPropertiesForType(int apiLevel) {
103: return propertyDescriptors(apiLevel);
104: }
105:
106: /* (omit javadoc for this method)
107: * Method declared on ASTNode.
108: */
109: final ASTNode internalGetSetChildProperty(
110: ChildPropertyDescriptor property, boolean get, ASTNode child) {
111: if (property == EXPRESSION_PROPERTY) {
112: if (get) {
113: return getExpression();
114: } else {
115: setExpression((Expression) child);
116: return null;
117: }
118: }
119: if (property == BODY_PROPERTY) {
120: if (get) {
121: return getBody();
122: } else {
123: setBody((Statement) child);
124: return null;
125: }
126: }
127: // allow default implementation to flag the error
128: return super .internalGetSetChildProperty(property, get, child);
129: }
130:
131: /* (omit javadoc for this method)
132: * Method declared on ASTNode.
133: */
134: final int getNodeType0() {
135: return WHILE_STATEMENT;
136: }
137:
138: /* (omit javadoc for this method)
139: * Method declared on ASTNode.
140: */
141: ASTNode clone0(AST target) {
142: WhileStatement result = new WhileStatement(target);
143: result
144: .setSourceRange(this .getStartPosition(), this
145: .getLength());
146: result.copyLeadingComment(this );
147: result
148: .setExpression((Expression) getExpression().clone(
149: target));
150: result.setBody((Statement) getBody().clone(target));
151: return result;
152: }
153:
154: /* (omit javadoc for this method)
155: * Method declared on ASTNode.
156: */
157: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
158: // dispatch to correct overloaded match method
159: return matcher.match(this , other);
160: }
161:
162: /* (omit javadoc for this method)
163: * Method declared on ASTNode.
164: */
165: void accept0(ASTVisitor visitor) {
166: boolean visitChildren = visitor.visit(this );
167: if (visitChildren) {
168: // visit children in normal left to right reading order
169: acceptChild(visitor, getExpression());
170: acceptChild(visitor, getBody());
171: }
172: visitor.endVisit(this );
173: }
174:
175: /**
176: * Returns the expression of this while statement.
177: *
178: * @return the expression node
179: */
180: public Expression getExpression() {
181: if (this .expression == null) {
182: // lazy init must be thread-safe for readers
183: synchronized (this ) {
184: if (this .expression == null) {
185: preLazyInit();
186: this .expression = new SimpleName(this .ast);
187: postLazyInit(this .expression, EXPRESSION_PROPERTY);
188: }
189: }
190: }
191: return this .expression;
192: }
193:
194: /**
195: * Sets the expression of this while statement.
196: *
197: * @param expression the expression node
198: * @exception IllegalArgumentException if:
199: * <ul>
200: * <li>the node belongs to a different AST</li>
201: * <li>the node already has a parent</li>
202: * <li>a cycle in would be created</li>
203: * </ul>
204: */
205: public void setExpression(Expression expression) {
206: if (expression == null) {
207: throw new IllegalArgumentException();
208: }
209: ASTNode oldChild = this .expression;
210: preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
211: this .expression = expression;
212: postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
213: }
214:
215: /**
216: * Returns the body of this while statement.
217: *
218: * @return the body statement node
219: */
220: public Statement getBody() {
221: if (this .body == null) {
222: // lazy init must be thread-safe for readers
223: synchronized (this ) {
224: if (this .body == null) {
225: preLazyInit();
226: this .body = new Block(this .ast);
227: postLazyInit(this .body, BODY_PROPERTY);
228: }
229: }
230: }
231: return this .body;
232: }
233:
234: /**
235: * Sets the body of this while statement.
236: * <p>
237: * Special note: The Java language does not allow a local variable declaration
238: * to appear as the body of a while statement (they may only appear within a
239: * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
240: * as the body of a <code>WhileStatement</code>. To get something that will
241: * compile, be sure to embed the <code>VariableDeclarationStatement</code>
242: * inside a <code>Block</code>.
243: * </p>
244: *
245: * @param statement the body statement node
246: * @exception IllegalArgumentException if:
247: * <ul>
248: * <li>the node belongs to a different AST</li>
249: * <li>the node already has a parent</li>
250: * <li>a cycle in would be created</li>
251: * </ul>
252: */
253: public void setBody(Statement statement) {
254: if (statement == null) {
255: throw new IllegalArgumentException();
256: }
257: ASTNode oldChild = this .body;
258: preReplaceChild(oldChild, statement, BODY_PROPERTY);
259: this .body = statement;
260: postReplaceChild(oldChild, statement, BODY_PROPERTY);
261: }
262:
263: /* (omit javadoc for this method)
264: * Method declared on ASTNode.
265: */
266: int memSize() {
267: return super .memSize() + 2 * 4;
268: }
269:
270: /* (omit javadoc for this method)
271: * Method declared on ASTNode.
272: */
273: int treeSize() {
274: return memSize()
275: + (this .expression == null ? 0 : getExpression()
276: .treeSize())
277: + (this .body == null ? 0 : getBody().treeSize());
278: }
279: }
|