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