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 case AST node type. A switch case is a special kind of node used only
017: * in switch statements. It is a <code>Statement</code> in name only.
018: * <p>
019: * <pre>
020: * SwitchCase:
021: * <b>case</b> Expression <b>:</b>
022: * <b>default</b> <b>:</b>
023: * </pre>
024: * </p>
025: *
026: * @since 2.0
027: */
028: public class SwitchCase extends Statement {
029:
030: /**
031: * The "expression" structural property of this node type.
032: * @since 3.0
033: */
034: public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = new ChildPropertyDescriptor(
035: SwitchCase.class,
036: "expression", Expression.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
037:
038: /**
039: * A list of property descriptors (element type:
040: * {@link StructuralPropertyDescriptor}),
041: * or null if uninitialized.
042: */
043: private static final List PROPERTY_DESCRIPTORS;
044:
045: static {
046: List propertyList = new ArrayList(2);
047: createPropertyList(SwitchCase.class, propertyList);
048: addProperty(EXPRESSION_PROPERTY, propertyList);
049: PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
050: }
051:
052: /**
053: * Returns a list of structural property descriptors for this node type.
054: * Clients must not modify the result.
055: *
056: * @param apiLevel the API level; one of the
057: * <code>AST.JLS*</code> constants
058: * @return a list of property descriptors (element type:
059: * {@link StructuralPropertyDescriptor})
060: * @since 3.0
061: */
062: public static List propertyDescriptors(int apiLevel) {
063: return PROPERTY_DESCRIPTORS;
064: }
065:
066: /**
067: * The expression; <code>null</code> for none; lazily initialized (but
068: * does <b>not</b> default to none).
069: * @see #expressionInitialized
070: */
071: private Expression optionalExpression = null;
072:
073: /**
074: * Indicates whether <code>optionalExpression</code> has been initialized.
075: */
076: private boolean expressionInitialized = false;
077:
078: /**
079: * Creates a new AST node for a switch case pseudo-statement owned by the
080: * given AST. By default, there is an unspecified, but legal, expression.
081: *
082: * @param ast the AST that is to own this node
083: */
084: SwitchCase(AST ast) {
085: super (ast);
086: }
087:
088: /* (omit javadoc for this method)
089: * Method declared on ASTNode.
090: */
091: final List internalStructuralPropertiesForType(int apiLevel) {
092: return propertyDescriptors(apiLevel);
093: }
094:
095: /* (omit javadoc for this method)
096: * Method declared on ASTNode.
097: */
098: final ASTNode internalGetSetChildProperty(
099: ChildPropertyDescriptor property, boolean get, ASTNode child) {
100: if (property == EXPRESSION_PROPERTY) {
101: if (get) {
102: return getExpression();
103: } else {
104: setExpression((Expression) child);
105: return null;
106: }
107: }
108: // allow default implementation to flag the error
109: return super .internalGetSetChildProperty(property, get, child);
110: }
111:
112: /* (omit javadoc for this method)
113: * Method declared on ASTNode.
114: */
115: final int getNodeType0() {
116: return SWITCH_CASE;
117: }
118:
119: /* (omit javadoc for this method)
120: * Method declared on ASTNode.
121: */
122: ASTNode clone0(AST target) {
123: SwitchCase result = new SwitchCase(target);
124: result
125: .setSourceRange(this .getStartPosition(), this
126: .getLength());
127: result.copyLeadingComment(this );
128: result.setExpression((Expression) ASTNode.copySubtree(target,
129: getExpression()));
130: return result;
131: }
132:
133: /* (omit javadoc for this method)
134: * Method declared on ASTNode.
135: */
136: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
137: // dispatch to correct overloaded match method
138: return matcher.match(this , other);
139: }
140:
141: /* (omit javadoc for this method)
142: * Method declared on ASTNode.
143: */
144: void accept0(ASTVisitor visitor) {
145: boolean visitChildren = visitor.visit(this );
146: if (visitChildren) {
147: acceptChild(visitor, getExpression());
148: }
149: visitor.endVisit(this );
150: }
151:
152: /**
153: * Returns the expression of this switch case, or
154: * <code>null</code> if there is none (the "default:" case).
155: *
156: * @return the expression node, or <code>null</code> if there is none
157: */
158: public Expression getExpression() {
159: if (!this .expressionInitialized) {
160: // lazy init must be thread-safe for readers
161: synchronized (this ) {
162: if (!this .expressionInitialized) {
163: preLazyInit();
164: this .optionalExpression = new SimpleName(this .ast);
165: this .expressionInitialized = true;
166: postLazyInit(this .optionalExpression,
167: EXPRESSION_PROPERTY);
168: }
169: }
170: }
171: return this .optionalExpression;
172: }
173:
174: /**
175: * Sets the expression of this switch case, or clears it (turns it into
176: * the "default:" case).
177: *
178: * @param expression the expression node, or <code>null</code> to
179: * turn it into the "default:" case
180: * @exception IllegalArgumentException if:
181: * <ul>
182: * <li>the node belongs to a different AST</li>
183: * <li>the node already has a parent</li>
184: * <li>a cycle in would be created</li>
185: * </ul>
186: */
187: public void setExpression(Expression expression) {
188: ASTNode oldChild = this .optionalExpression;
189: preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
190: this .optionalExpression = expression;
191: this .expressionInitialized = true;
192: postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
193: }
194:
195: /**
196: * Returns whether this switch case represents the "default:" case.
197: * <p>
198: * This convenience method is equivalent to
199: * <code>getExpression() == null</code>.
200: * </p>
201: *
202: * @return <code>true</code> if this is the default switch case, and
203: * <code>false</code> if this is a non-default switch case
204: */
205: public boolean isDefault() {
206: return getExpression() == null;
207: }
208:
209: /* (omit javadoc for this method)
210: * Method declared on ASTNode.
211: */
212: int memSize() {
213: return super .memSize() + 2 * 4;
214: }
215:
216: /* (omit javadoc for this method)
217: * Method declared on ASTNode.
218: */
219: int treeSize() {
220: return memSize()
221: + (this .optionalExpression == null ? 0
222: : optionalExpression.treeSize());
223: }
224: }
|