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 * Labeled statement AST node type.
22 * Identifier <b>:</b> Statement
26 * @noinstantiate This class is not intended to be instantiated by clients.
28 public class LabeledStatement extends Statement {
31 * The "label" structural property of this node type.
34 public static final ChildPropertyDescriptor LABEL_PROPERTY =
35 new ChildPropertyDescriptor(LabeledStatement.class, "label", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
38 * The "body" structural property of this node type.
41 public static final ChildPropertyDescriptor BODY_PROPERTY =
42 new ChildPropertyDescriptor(LabeledStatement.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(LabeledStatement.class, propertyList);
54 addProperty(LABEL_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 label; lazily initialized; defaults to a unspecified,
76 * legal Java identifier.
78 private SimpleName labelName = null;
81 * The body statement; lazily initialized; defaults to an unspecified, but
84 private Statement body = null;
87 * Creates a new AST node for a labeled statement owned by the given
88 * AST. By default, the statement has an unspecified (but legal) label
89 * and an unspecified (but legal) statement.
91 * N.B. This constructor is package-private.
94 * @param ast the AST that is to own this node
96 LabeledStatement(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 == LABEL_PROPERTY) {
115 setLabel((SimpleName) 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 LABELED_STATEMENT;
138 /* (omit javadoc for this method)
139 * Method declared on ASTNode.
141 ASTNode clone0(AST target) {
142 LabeledStatement result = new LabeledStatement(target);
143 result.setSourceRange(this.getStartPosition(), this.getLength());
145 (SimpleName) ASTNode.copySubtree(target, getLabel()));
147 (Statement) ASTNode.copySubtree(target, getBody()));
151 /* (omit javadoc for this method)
152 * Method declared on ASTNode.
154 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
155 // dispatch to correct overloaded match method
156 return matcher.match(this, other);
159 /* (omit javadoc for this method)
160 * Method declared on ASTNode.
162 void accept0(ASTVisitor visitor) {
163 boolean visitChildren = visitor.visit(this);
165 // visit children in normal left to right reading order
166 acceptChild(visitor, getLabel());
167 acceptChild(visitor, getBody());
169 visitor.endVisit(this);
173 * Returns the label of this labeled statement.
175 * @return the variable name node
177 public SimpleName getLabel() {
178 if (this.labelName == null) {
179 // lazy init must be thread-safe for readers
180 synchronized (this) {
181 if (this.labelName == null) {
183 this.labelName= new SimpleName(this.ast);
184 postLazyInit(this.labelName, LABEL_PROPERTY);
188 return this.labelName;
192 * Sets the label of this labeled statement.
194 * @param label the new label
195 * @exception IllegalArgumentException if:
197 * <li>the node belongs to a different AST</li>
198 * <li>the node already has a parent</li>
201 public void setLabel(SimpleName label) {
203 throw new IllegalArgumentException();
205 ASTNode oldChild = this.labelName;
206 preReplaceChild(oldChild, label, LABEL_PROPERTY);
207 this.labelName = label;
208 postReplaceChild(oldChild, label, LABEL_PROPERTY);
212 * Returns the body of this labeled 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 EmptyStatement(this.ast);
223 postLazyInit(this.body, BODY_PROPERTY);
231 * Sets the body of this labeled statement.
233 * Special note: The Java language does not allow a local variable declaration
234 * to appear as the body of a labeled 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>LabeledStatement</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.labelName == null ? 0 : getLabel().treeSize())
273 + (this.body == null ? 0 : getBody().treeSize());