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: * Array access expression AST node type.
017: *
018: * <pre>
019: * ArrayAccess:
020: * Expression <b>[</b> Expression <b>]</b>
021: * </pre>
022: *
023: * @since 2.0
024: */
025: public class ArrayAccess extends Expression {
026:
027: /**
028: * The "array" structural property of this node type.
029: * @since 3.0
030: */
031: public static final ChildPropertyDescriptor ARRAY_PROPERTY = new ChildPropertyDescriptor(
032: ArrayAccess.class,
033: "array", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
034:
035: /**
036: * The "index" structural property of this node type.
037: * @since 3.0
038: */
039: public static final ChildPropertyDescriptor INDEX_PROPERTY = new ChildPropertyDescriptor(
040: ArrayAccess.class,
041: "index", 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(ArrayAccess.class, properyList);
053: addProperty(ARRAY_PROPERTY, properyList);
054: addProperty(INDEX_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:
065: * @return a list of property descriptors (element type:
066: * {@link StructuralPropertyDescriptor})
067: * @since 3.0
068: */
069: public static List propertyDescriptors(int apiLevel) {
070: return PROPERTY_DESCRIPTORS;
071: }
072:
073: /**
074: * The array expression; lazily initialized; defaults to an unspecified,
075: * but legal, expression.
076: */
077: private Expression arrayExpression = null;
078:
079: /**
080: * The index expression; lazily initialized; defaults to an unspecified,
081: * but legal, expression.
082: */
083: private Expression indexExpression = null;
084:
085: /**
086: * Creates a new unparented array access expression node owned by the given
087: * AST. By default, the array and index expresssions are unspecified,
088: * but legal.
089: * <p>
090: * N.B. This constructor is package-private.
091: * </p>
092: *
093: * @param ast the AST that is to own this node
094: */
095: ArrayAccess(AST ast) {
096: super (ast);
097: }
098:
099: /* (omit javadoc for this method)
100: * Method declared on ASTNode.
101: */
102: final List internalStructuralPropertiesForType(int apiLevel) {
103: return propertyDescriptors(apiLevel);
104: }
105:
106: /* (omit javadoc for this method)
107: * Method declared on ASTNode.
108: */
109: final ASTNode internalGetSetChildProperty(
110: ChildPropertyDescriptor property, boolean get, ASTNode child) {
111: if (property == ARRAY_PROPERTY) {
112: if (get) {
113: return getArray();
114: } else {
115: setArray((Expression) child);
116: return null;
117: }
118: }
119: if (property == INDEX_PROPERTY) {
120: if (get) {
121: return getIndex();
122: } else {
123: setIndex((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 int getNodeType0() {
135: return ARRAY_ACCESS;
136: }
137:
138: /* (omit javadoc for this method)
139: * Method declared on ASTNode.
140: */
141: ASTNode clone0(AST target) {
142: ArrayAccess result = new ArrayAccess(target);
143: result
144: .setSourceRange(this .getStartPosition(), this
145: .getLength());
146: result.setArray((Expression) getArray().clone(target));
147: result.setIndex((Expression) getIndex().clone(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, getArray());
167: acceptChild(visitor, getIndex());
168: }
169: visitor.endVisit(this );
170: }
171:
172: /**
173: * Returns the array expression of this array access expression.
174: *
175: * @return the array expression node
176: */
177: public Expression getArray() {
178: if (this .arrayExpression == null) {
179: // lazy init must be thread-safe for readers
180: synchronized (this ) {
181: if (this .arrayExpression == null) {
182: preLazyInit();
183: this .arrayExpression = new SimpleName(this .ast);
184: postLazyInit(this .arrayExpression, ARRAY_PROPERTY);
185: }
186: }
187: }
188: return this .arrayExpression;
189: }
190:
191: /**
192: * Sets the array expression of this array access expression.
193: *
194: * @param expression the array expression node
195: * @exception IllegalArgumentException if:
196: * <ul>
197: * <li>the node belongs to a different AST</li>
198: * <li>the node already has a parent</li>
199: * <li>a cycle in would be created</li>
200: * </ul>
201: */
202: public void setArray(Expression expression) {
203: if (expression == null) {
204: throw new IllegalArgumentException();
205: }
206: // an ArrayAccess may occur inside an Expression
207: // must check cycles
208: ASTNode oldChild = this .arrayExpression;
209: preReplaceChild(oldChild, expression, ARRAY_PROPERTY);
210: this .arrayExpression = expression;
211: postReplaceChild(oldChild, expression, ARRAY_PROPERTY);
212: }
213:
214: /**
215: * Returns the index expression of this array access expression.
216: *
217: * @return the index expression node
218: */
219: public Expression getIndex() {
220: if (this .indexExpression == null) {
221: // lazy init must be thread-safe for readers
222: synchronized (this ) {
223: if (this .indexExpression == null) {
224: preLazyInit();
225: this .indexExpression = new SimpleName(this .ast);
226: postLazyInit(this .indexExpression, INDEX_PROPERTY);
227: }
228: }
229: }
230: return this .indexExpression;
231: }
232:
233: /**
234: * Sets the index expression of this array access expression.
235: *
236: * @param expression the index expression node
237: * @exception IllegalArgumentException if:
238: * <ul>
239: * <li>the node belongs to a different AST</li>
240: * <li>the node already has a parent</li>
241: * <li>a cycle in would be created</li>
242: * </ul>
243: */
244: public void setIndex(Expression expression) {
245: if (expression == null) {
246: throw new IllegalArgumentException();
247: }
248: // an ArrayAccess may occur inside an Expression
249: // must check cycles
250: ASTNode oldChild = this .indexExpression;
251: preReplaceChild(oldChild, expression, INDEX_PROPERTY);
252: this .indexExpression = expression;
253: postReplaceChild(oldChild, expression, INDEX_PROPERTY);
254: }
255:
256: /* (omit javadoc for this method)
257: * Method declared on ASTNode.
258: */
259: int memSize() {
260: return BASE_NODE_SIZE + 2 * 4;
261: }
262:
263: /* (omit javadoc for this method)
264: * Method declared on ASTNode.
265: */
266: int treeSize() {
267: return memSize()
268: + (this .arrayExpression == null ? 0 : getArray()
269: .treeSize())
270: + (this .indexExpression == null ? 0 : getIndex()
271: .treeSize());
272: }
273: }
|