1 /*******************************************************************************
2 * Copyright (c) 2000, 2008 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
12 package net.sourceforge.phpdt.core.dom;
14 import java.util.ArrayList;
15 import java.util.List;
18 * Array access expression AST node type.
22 * Expression <b>[</b> Expression <b>]</b>
26 * @noinstantiate This class is not intended to be instantiated by clients.
28 public class ArrayAccess extends Expression {
31 * The "array" structural property of this node type.
34 public static final ChildPropertyDescriptor ARRAY_PROPERTY =
35 new ChildPropertyDescriptor(ArrayAccess.class, "array", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
38 * The "index" structural property of this node type.
41 public static final ChildPropertyDescriptor INDEX_PROPERTY =
42 new ChildPropertyDescriptor(ArrayAccess.class, "index", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
45 * A list of property descriptors (element type:
46 * {@link StructuralPropertyDescriptor}),
47 * or null if uninitialized.
49 private static final List PROPERTY_DESCRIPTORS;
52 List properyList = new ArrayList(3);
53 createPropertyList(ArrayAccess.class, properyList);
54 addProperty(ARRAY_PROPERTY, properyList);
55 addProperty(INDEX_PROPERTY, properyList);
56 PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
60 * Returns a list of structural property descriptors for this node type.
61 * Clients must not modify the result.
63 * @param apiLevel the API level; one of the
64 * <code>AST.JLS*</code> constants
66 * @return a list of property descriptors (element type:
67 * {@link StructuralPropertyDescriptor})
70 public static List propertyDescriptors(int apiLevel) {
71 return PROPERTY_DESCRIPTORS;
75 * The array expression; lazily initialized; defaults to an unspecified,
76 * but legal, expression.
78 private Expression arrayExpression = null;
81 * The index expression; lazily initialized; defaults to an unspecified,
82 * but legal, expression.
84 private Expression indexExpression = null;
87 * Creates a new unparented array access expression node owned by the given
88 * AST. By default, the array and index expresssions are unspecified,
91 * N.B. This constructor is package-private.
94 * @param ast the AST that is to own this node
96 ArrayAccess(AST ast) {
100 /* (omit javadoc for this method)
101 * Method declared on ASTNode.
103 final List internalStructuralPropertiesForType(int apiLevel) {
104 return propertyDescriptors(apiLevel);
107 /* (omit javadoc for this method)
108 * Method declared on ASTNode.
110 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
111 if (property == ARRAY_PROPERTY) {
115 setArray((Expression) child);
119 if (property == INDEX_PROPERTY) {
123 setIndex((Expression) child);
127 // allow default implementation to flag the error
128 return super.internalGetSetChildProperty(property, get, child);
131 /* (omit javadoc for this method)
132 * Method declared on ASTNode.
134 final int getNodeType0() {
138 /* (omit javadoc for this method)
139 * Method declared on ASTNode.
141 ASTNode clone0(AST target) {
142 ArrayAccess result = new ArrayAccess(target);
143 result.setSourceRange(this.getStartPosition(), this.getLength());
144 result.setArray((Expression) getArray().clone(target));
145 result.setIndex((Expression) getIndex().clone(target));
149 /* (omit javadoc for this method)
150 * Method declared on ASTNode.
152 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
153 // dispatch to correct overloaded match method
154 return matcher.match(this, other);
157 /* (omit javadoc for this method)
158 * Method declared on ASTNode.
160 void accept0(ASTVisitor visitor) {
161 boolean visitChildren = visitor.visit(this);
163 // visit children in normal left to right reading order
164 acceptChild(visitor, getArray());
165 acceptChild(visitor, getIndex());
167 visitor.endVisit(this);
171 * Returns the array expression of this array access expression.
173 * @return the array expression node
175 public Expression getArray() {
176 if (this.arrayExpression == null) {
177 // lazy init must be thread-safe for readers
178 synchronized (this) {
179 if (this.arrayExpression == null) {
181 this.arrayExpression = new SimpleName(this.ast);
182 postLazyInit(this.arrayExpression, ARRAY_PROPERTY);
186 return this.arrayExpression;
190 * Sets the array expression of this array access expression.
192 * @param expression the array expression node
193 * @exception IllegalArgumentException if:
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>
200 public void setArray(Expression expression) {
201 if (expression == null) {
202 throw new IllegalArgumentException();
204 // an ArrayAccess may occur inside an Expression
206 ASTNode oldChild = this.arrayExpression;
207 preReplaceChild(oldChild, expression, ARRAY_PROPERTY);
208 this.arrayExpression = expression;
209 postReplaceChild(oldChild, expression, ARRAY_PROPERTY);
213 * Returns the index expression of this array access expression.
215 * @return the index expression node
217 public Expression getIndex() {
218 if (this.indexExpression == null) {
219 // lazy init must be thread-safe for readers
220 synchronized (this) {
221 if (this.indexExpression == null) {
223 this.indexExpression = new SimpleName(this.ast);
224 postLazyInit(this.indexExpression, INDEX_PROPERTY);
228 return this.indexExpression;
232 * Sets the index expression of this array access expression.
234 * @param expression the index expression node
235 * @exception IllegalArgumentException if:
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>
242 public void setIndex(Expression expression) {
243 if (expression == null) {
244 throw new IllegalArgumentException();
246 // an ArrayAccess may occur inside an Expression
248 ASTNode oldChild = this.indexExpression;
249 preReplaceChild(oldChild, expression, INDEX_PROPERTY);
250 this.indexExpression = expression;
251 postReplaceChild(oldChild, expression, INDEX_PROPERTY);
254 /* (omit javadoc for this method)
255 * Method declared on ASTNode.
258 return BASE_NODE_SIZE + 2 * 4;
261 /* (omit javadoc for this method)
262 * Method declared on ASTNode.
267 + (this.arrayExpression == null ? 0 : getArray().treeSize())
268 + (this.indexExpression == null ? 0 : getIndex().treeSize());