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: * Cast expression AST node type.
017: *
018: * <pre>
019: * CastExpression:
020: * <b>(</b> Type <b>)</b> Expression
021: * </pre>
022: *
023: * @since 2.0
024: */
025: public class CastExpression extends Expression {
026:
027: /**
028: * The "type" structural property of this node type.
029: * @since 3.0
030: */
031: public static final ChildPropertyDescriptor TYPE_PROPERTY = new ChildPropertyDescriptor(
032: CastExpression.class,
033: "type", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
034:
035: /**
036: * The "expression" structural property of this node type.
037: * @since 3.0
038: */
039: public static final ChildPropertyDescriptor EXPRESSION_PROPERTY = new ChildPropertyDescriptor(
040: CastExpression.class,
041: "expression", Expression.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 properyList = new ArrayList(3);
052: createPropertyList(CastExpression.class, properyList);
053: addProperty(TYPE_PROPERTY, properyList);
054: addProperty(EXPRESSION_PROPERTY, properyList);
055: PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
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: * @return a list of property descriptors (element type:
065: * {@link StructuralPropertyDescriptor})
066: * @since 3.0
067: */
068: public static List propertyDescriptors(int apiLevel) {
069: return PROPERTY_DESCRIPTORS;
070: }
071:
072: /**
073: * The type; lazily initialized; defaults to a unspecified,
074: * legal type.
075: */
076: private Type type = null;
077:
078: /**
079: * The expression; lazily initialized; defaults to a unspecified, but legal,
080: * expression.
081: */
082: private Expression expression = null;
083:
084: /**
085: * Creates a new AST node for a cast expression owned by the given
086: * AST. By default, the type and expression are unspecified (but legal).
087: * <p>
088: * N.B. This constructor is package-private.
089: * </p>
090: *
091: * @param ast the AST that is to own this node
092: */
093: CastExpression(AST ast) {
094: super (ast);
095: }
096:
097: /* (omit javadoc for this method)
098: * Method declared on ASTNode.
099: */
100: final List internalStructuralPropertiesForType(int apiLevel) {
101: return propertyDescriptors(apiLevel);
102: }
103:
104: /* (omit javadoc for this method)
105: * Method declared on ASTNode.
106: */
107: final ASTNode internalGetSetChildProperty(
108: ChildPropertyDescriptor property, boolean get, ASTNode child) {
109: if (property == EXPRESSION_PROPERTY) {
110: if (get) {
111: return getExpression();
112: } else {
113: setExpression((Expression) child);
114: return null;
115: }
116: }
117: if (property == TYPE_PROPERTY) {
118: if (get) {
119: return getType();
120: } else {
121: setType((Type) child);
122: return null;
123: }
124: }
125: // allow default implementation to flag the error
126: return super .internalGetSetChildProperty(property, get, child);
127: }
128:
129: /* (omit javadoc for this method)
130: * Method declared on ASTNode.
131: */
132: final int getNodeType0() {
133: return CAST_EXPRESSION;
134: }
135:
136: /* (omit javadoc for this method)
137: * Method declared on ASTNode.
138: */
139: ASTNode clone0(AST target) {
140: CastExpression result = new CastExpression(target);
141: result
142: .setSourceRange(this .getStartPosition(), this
143: .getLength());
144: result.setType((Type) getType().clone(target));
145: result
146: .setExpression((Expression) getExpression().clone(
147: target));
148: return result;
149: }
150:
151: /* (omit javadoc for this method)
152: * Method declared on ASTNode.
153: */
154: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
155: // dispatch to correct overloaded match method
156: return matcher.match(this , other);
157: }
158:
159: /* (omit javadoc for this method)
160: * Method declared on ASTNode.
161: */
162: void accept0(ASTVisitor visitor) {
163: boolean visitChildren = visitor.visit(this );
164: if (visitChildren) {
165: // visit children in normal left to right reading order
166: acceptChild(visitor, getType());
167: acceptChild(visitor, getExpression());
168: }
169: visitor.endVisit(this );
170: }
171:
172: /**
173: * Returns the type in this cast expression.
174: *
175: * @return the type
176: */
177: public Type getType() {
178: if (this .type == null) {
179: // lazy init must be thread-safe for readers
180: synchronized (this ) {
181: if (this .type == null) {
182: preLazyInit();
183: this .type = this .ast
184: .newPrimitiveType(PrimitiveType.INT);
185: postLazyInit(this .type, TYPE_PROPERTY);
186: }
187: }
188: }
189: return this .type;
190: }
191:
192: /**
193: * Sets the type in this cast expression to the given type.
194: *
195: * @param type the new type
196: * @exception IllegalArgumentException if:
197: * <ul>
198: * <li>the node belongs to a different AST</li>
199: * <li>the node already has a parent</li>
200: * </ul>
201: */
202: public void setType(Type type) {
203: if (type == null) {
204: throw new IllegalArgumentException();
205: }
206: ASTNode oldChild = this .type;
207: preReplaceChild(oldChild, type, TYPE_PROPERTY);
208: this .type = type;
209: postReplaceChild(oldChild, type, TYPE_PROPERTY);
210: }
211:
212: /**
213: * Returns the expression of this cast expression.
214: *
215: * @return the expression node
216: */
217: public Expression getExpression() {
218: if (this .expression == null) {
219: // lazy init must be thread-safe for readers
220: synchronized (this ) {
221: if (this .expression == null) {
222: preLazyInit();
223: this .expression = new SimpleName(this .ast);
224: postLazyInit(this .expression, EXPRESSION_PROPERTY);
225: }
226: }
227: }
228: return this .expression;
229: }
230:
231: /**
232: * Sets the expression of this cast expression.
233: *
234: * @param expression the new expression node
235: * @exception IllegalArgumentException if:
236: * <ul>
237: * <li>the node belongs to a different AST</li>
238: * <li>the node already has a parent</li>
239: * <li>a cycle in would be created</li>
240: * </ul>
241: */
242: public void setExpression(Expression expression) {
243: if (expression == null) {
244: throw new IllegalArgumentException();
245: }
246: ASTNode oldChild = this .expression;
247: preReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
248: this .expression = expression;
249: postReplaceChild(oldChild, expression, EXPRESSION_PROPERTY);
250: }
251:
252: /* (omit javadoc for this method)
253: * Method declared on ASTNode.
254: */
255: int memSize() {
256: // treat Code as free
257: return BASE_NODE_SIZE + 2 * 4;
258: }
259:
260: /* (omit javadoc for this method)
261: * Method declared on ASTNode.
262: */
263: int treeSize() {
264: return memSize()
265: + (this .expression == null ? 0 : getExpression()
266: .treeSize())
267: + (this .type == null ? 0 : getType().treeSize());
268: }
269: }
|