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