278a80ee15b2be37413131387aa6b2cb06f1eb5a
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / ArrayAccess.java
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
7  *
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11
12 package net.sourceforge.phpdt.core.dom;
13
14 import java.util.ArrayList;
15 import java.util.List;
16
17 /**
18  * Array access expression AST node type.
19  *
20  * <pre>
21  * ArrayAccess:
22  *    Expression <b>[</b> Expression <b>]</b>
23  * </pre>
24  * 
25  * @since 2.0
26  * @noinstantiate This class is not intended to be instantiated by clients.
27  */
28 public class ArrayAccess extends Expression {
29         
30         /**
31          * The "array" structural property of this node type.
32          * @since 3.0
33          */
34         public static final ChildPropertyDescriptor ARRAY_PROPERTY = 
35                 new ChildPropertyDescriptor(ArrayAccess.class, "array", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
36
37         /**
38          * The "index" structural property of this node type.
39          * @since 3.0
40          */
41         public static final ChildPropertyDescriptor INDEX_PROPERTY = 
42                 new ChildPropertyDescriptor(ArrayAccess.class, "index", Expression.class, MANDATORY, CYCLE_RISK); //$NON-NLS-1$
43
44         /**
45          * A list of property descriptors (element type: 
46          * {@link StructuralPropertyDescriptor}),
47          * or null if uninitialized.
48          */
49         private static final List PROPERTY_DESCRIPTORS;
50         
51         static {
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);
57         }
58
59         /**
60          * Returns a list of structural property descriptors for this node type.
61          * Clients must not modify the result.
62          * 
63          * @param apiLevel the API level; one of the
64          * <code>AST.JLS*</code> constants
65
66          * @return a list of property descriptors (element type: 
67          * {@link StructuralPropertyDescriptor})
68          * @since 3.0
69          */
70         public static List propertyDescriptors(int apiLevel) {
71                 return PROPERTY_DESCRIPTORS;
72         }
73                         
74         /**
75          * The array expression; lazily initialized; defaults to an unspecified,
76          * but legal, expression.
77          */
78         private Expression arrayExpression = null;
79
80         /**
81          * The index expression; lazily initialized; defaults to an unspecified,
82          * but legal, expression.
83          */
84         private Expression indexExpression = null;
85
86         /**
87          * Creates a new unparented array access expression node owned by the given 
88          * AST. By default, the array and index expresssions are unspecified, 
89          * but legal.
90          * <p>
91          * N.B. This constructor is package-private.
92          * </p>
93          * 
94          * @param ast the AST that is to own this node
95          */
96         ArrayAccess(AST ast) {
97                 super(ast);
98         }
99
100         /* (omit javadoc for this method)
101          * Method declared on ASTNode.
102          */
103         final List internalStructuralPropertiesForType(int apiLevel) {
104                 return propertyDescriptors(apiLevel);
105         }
106         
107         /* (omit javadoc for this method)
108          * Method declared on ASTNode.
109          */
110         final ASTNode internalGetSetChildProperty(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.setSourceRange(this.getStartPosition(), this.getLength());
144                 result.setArray((Expression) getArray().clone(target));
145                 result.setIndex((Expression) getIndex().clone(target));
146                 return result;
147         }
148
149         /* (omit javadoc for this method)
150          * Method declared on ASTNode.
151          */
152         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
153                 // dispatch to correct overloaded match method
154                 return matcher.match(this, other);
155         }
156
157         /* (omit javadoc for this method)
158          * Method declared on ASTNode.
159          */
160         void accept0(ASTVisitor visitor) {
161                 boolean visitChildren = visitor.visit(this);
162                 if (visitChildren) {
163                         // visit children in normal left to right reading order
164                         acceptChild(visitor, getArray());
165                         acceptChild(visitor, getIndex());
166                 }
167                 visitor.endVisit(this);
168         }
169         
170         /**
171          * Returns the array expression of this array access expression.
172          * 
173          * @return the array expression node
174          */ 
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) {
180                                         preLazyInit();
181                                         this.arrayExpression = new SimpleName(this.ast);
182                                         postLazyInit(this.arrayExpression, ARRAY_PROPERTY);
183                                 }
184                         }
185                 }
186                 return this.arrayExpression;
187         }
188         
189         /**
190          * Sets the array expression of this array access expression.
191          * 
192          * @param expression the array expression 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 setArray(Expression expression) {
201                 if (expression == null) {
202                         throw new IllegalArgumentException();
203                 }
204                 // an ArrayAccess may occur inside an Expression
205                 // must check cycles
206                 ASTNode oldChild = this.arrayExpression;
207                 preReplaceChild(oldChild, expression, ARRAY_PROPERTY);
208                 this.arrayExpression = expression;
209                 postReplaceChild(oldChild, expression, ARRAY_PROPERTY);
210         }
211         
212         /**
213          * Returns the index expression of this array access expression.
214          * 
215          * @return the index expression node
216          */ 
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) {
222                                         preLazyInit();
223                                         this.indexExpression = new SimpleName(this.ast);
224                                         postLazyInit(this.indexExpression, INDEX_PROPERTY);
225                                 }
226                         }
227                 }
228                 return this.indexExpression;
229         }
230         
231         /**
232          * Sets the index expression of this array access expression.
233          * 
234          * @param expression the index 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 setIndex(Expression expression) {
243                 if (expression == null) {
244                         throw new IllegalArgumentException();
245                 }
246                 // an ArrayAccess may occur inside an Expression
247                 // must check cycles
248                 ASTNode oldChild = this.indexExpression;
249                 preReplaceChild(oldChild, expression, INDEX_PROPERTY);
250                 this.indexExpression = expression;
251                 postReplaceChild(oldChild, expression, INDEX_PROPERTY);
252         }
253
254         /* (omit javadoc for this method)
255          * Method declared on ASTNode.
256          */
257         int memSize() {
258                 return BASE_NODE_SIZE + 2 * 4;
259         }
260
261         /* (omit javadoc for this method)
262          * Method declared on ASTNode.
263          */
264         int treeSize() {
265                 return
266                         memSize()
267                         + (this.arrayExpression == null ? 0 : getArray().treeSize())
268                         + (this.indexExpression == null ? 0 : getIndex().treeSize());
269         }
270 }
271