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  * While statement AST node type.
 
  22  *    <b>while</b> <b>(</b> Expression <b>)</b> Statement
 
  26  * @noinstantiate This class is not intended to be instantiated by clients.
 
  28 public class WhileStatement extends Statement {
 
  31          * The "expression" structural property of this node type.
 
  34         public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = 
 
  35                 new ChildPropertyDescriptor(WhileStatement.class, "expression", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
  38          * The "body" structural property of this node type.
 
  41         public static final ChildPropertyDescriptor BODY_PROPERTY = 
 
  42                 new ChildPropertyDescriptor(WhileStatement.class, "body", Statement.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
 
  45          * A list of property descriptors (element type: 
 
  46          * {@link StructuralPropertyDescriptor}),
 
  47          * or null if uninitialized.
 
  49         private static final List PROPERTY_DESCRIPTORS;
 
  52                 List propertyList = new ArrayList(3);
 
  53                 createPropertyList(WhileStatement.class, propertyList);
 
  54                 addProperty(EXPRESSION_PROPERTY, propertyList);
 
  55                 addProperty(BODY_PROPERTY, propertyList);
 
  56                 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
 
  60          * Returns a list of structural property descriptors for this node type.
 
  61          * Clients must not modify the result.
 
  63          * @param apiLevel the API level; one of the
 
  64          * <code>AST.JLS*</code> constants
 
  66          * @return a list of property descriptors (element type: 
 
  67          * {@link StructuralPropertyDescriptor})
 
  70         public static List propertyDescriptors(int apiLevel) {
 
  71                 return PROPERTY_DESCRIPTORS;
 
  75          * The expression; lazily initialized; defaults to an unspecified, but 
 
  78         private Expression expression = null;
 
  81          * The body statement; lazily initialized; defaults to an empty block 
 
  84         private Statement body = null;
 
  87          * Creates a new unparented while statement node owned by the given 
 
  88          * AST. By default, the expresssion is unspecified, but legal, and
 
  89          * the body statement is an empty block.
 
  91          * N.B. This constructor is package-private.
 
  94          * @param ast the AST that is to own this node
 
  96         WhileStatement(AST ast) {
 
 100         /* (omit javadoc for this method)
 
 101          * Method declared on ASTNode.
 
 103         final List internalStructuralPropertiesForType(int apiLevel) {
 
 104                 return propertyDescriptors(apiLevel);
 
 107         /* (omit javadoc for this method)
 
 108          * Method declared on ASTNode.
 
 110         final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
 
 111                 if (property == EXPRESSION_PROPERTY) {
 
 113                                 return getExpression();
 
 115                                 setExpression((Expression) child);
 
 119                 if (property == BODY_PROPERTY) {
 
 123                                 setBody((Statement) child);
 
 127                 // allow default implementation to flag the error
 
 128                 return super.internalGetSetChildProperty(property, get, child);
 
 131         /* (omit javadoc for this method)
 
 132          * Method declared on ASTNode.
 
 134         final int getNodeType0() {
 
 135                 return WHILE_STATEMENT;
 
 138         /* (omit javadoc for this method)
 
 139          * Method declared on ASTNode.
 
 141         ASTNode clone0(AST target) {
 
 142                 WhileStatement result = new WhileStatement(target);
 
 143                 result.setSourceRange(this.getStartPosition(), this.getLength());
 
 144                 result.copyLeadingComment(this);
 
 145                 result.setExpression((Expression) getExpression().clone(target));
 
 146                 result.setBody((Statement) getBody().clone(target));
 
 150         /* (omit javadoc for this method)
 
 151          * Method declared on ASTNode.
 
 153         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
 
 154                 // dispatch to correct overloaded match method
 
 155                 return matcher.match(this, other);
 
 158         /* (omit javadoc for this method)
 
 159          * Method declared on ASTNode.
 
 161         void accept0(ASTVisitor visitor) {
 
 162                 boolean visitChildren = visitor.visit(this);
 
 164                         // visit children in normal left to right reading order
 
 165                         acceptChild(visitor, getExpression());
 
 166                         acceptChild(visitor, getBody());
 
 168                 visitor.endVisit(this);
 
 172          * Returns the expression of this while statement.
 
 174          * @return the expression node
 
 176         public Expression getExpression() {
 
 177                 if (this.expression == null) {
 
 178                         // lazy init must be thread-safe for readers
 
 179                         synchronized (this) {
 
 180                                 if (this.expression == null) {
 
 182                                         this.expression = new SimpleName(this.ast);
 
 183                                         postLazyInit(this.expression, EXPRESSION_PROPERTY);
 
 187                 return this.expression;
 
 191          * Sets the expression of this while statement.
 
 193          * @param expression the expression node
 
 194          * @exception IllegalArgumentException if:
 
 196          * <li>the node belongs to a different AST</li>
 
 197          * <li>the node already has a parent</li>
 
 198          * <li>a cycle in would be created</li>
 
 201         public void setExpression(Expression expression) {
 
 202                 if (expression == null) {
 
 203                         throw new IllegalArgumentException();
 
 205                 ASTNode oldChild = this.expression;
 
 206                 preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
 
 207                 this.expression = expression;
 
 208                 postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
 
 212          * Returns the body of this while statement.
 
 214          * @return the body statement node
 
 216         public Statement getBody() {
 
 217                 if (this.body == null) {
 
 218                         // lazy init must be thread-safe for readers
 
 219                         synchronized (this) {
 
 220                                 if (this.body == null) {
 
 222                                         this.body = new Block(this.ast);
 
 223                                         postLazyInit(this.body, BODY_PROPERTY);
 
 231          * Sets the body of this while statement.
 
 233          * Special note: The Java language does not allow a local variable declaration
 
 234          * to appear as the body of a while statement (they may only appear within a
 
 235          * block). However, the AST will allow a <code>VariableDeclarationStatement</code>
 
 236          * as the body of a <code>WhileStatement</code>. To get something that will
 
 237          * compile, be sure to embed the <code>VariableDeclarationStatement</code>
 
 238          * inside a <code>Block</code>.
 
 241          * @param statement the body statement node
 
 242          * @exception IllegalArgumentException if:
 
 244          * <li>the node belongs to a different AST</li>
 
 245          * <li>the node already has a parent</li>
 
 246          * <li>a cycle in would be created</li>
 
 249         public void setBody(Statement statement) {
 
 250                 if (statement == null) {
 
 251                         throw new IllegalArgumentException();
 
 253                 ASTNode oldChild = this.body;
 
 254                 preReplaceChild(oldChild, statement, BODY_PROPERTY);
 
 255                 this.body = statement;
 
 256                 postReplaceChild(oldChild, statement, BODY_PROPERTY);
 
 259         /* (omit javadoc for this method)
 
 260          * Method declared on ASTNode.
 
 263                 return super.memSize() + 2 * 4;
 
 266         /* (omit javadoc for this method)
 
 267          * Method declared on ASTNode.
 
 272                         + (this.expression == null ? 0 : getExpression().treeSize())
 
 273                         + (this.body == null ? 0 : getBody().treeSize());