31e67a783d202111717d1da0083187e21d842963
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / core / dom / SuperFieldAccess.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  * Simple or qualified "super" field access expression AST node type.
19  *
20  * <pre>
21  * SuperFieldAccess:
22  *     [ ClassName <b>.</b> ] <b>super</b> <b>.</b> Identifier
23  * </pre>
24  * 
25  * <p>
26  * See <code>FieldAccess</code> for guidelines on handling other expressions
27  * that resemble qualified names.
28  * </p>
29  * 
30  * @see FieldAccess
31  * @since 2.0
32  * @noinstantiate This class is not intended to be instantiated by clients.
33  */
34 public class SuperFieldAccess extends Expression {
35
36         /**
37          * The "qualifier" structural property of this node type.
38          * @since 3.0
39          */
40         public static final ChildPropertyDescriptor QUALIFIER_PROPERTY = 
41                 new ChildPropertyDescriptor(SuperFieldAccess.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
42
43         /**
44          * The "name" structural property of this node type.
45          * @since 3.0
46          */
47         public static final ChildPropertyDescriptor NAME_PROPERTY = 
48                 new ChildPropertyDescriptor(SuperFieldAccess.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
49
50         /**
51          * A list of property descriptors (element type: 
52          * {@link StructuralPropertyDescriptor}),
53          * or null if uninitialized.
54          */
55         private static final List PROPERTY_DESCRIPTORS;
56         
57         static {
58                 List propertyList = new ArrayList(3);
59                 createPropertyList(SuperFieldAccess.class, propertyList);
60                 addProperty(QUALIFIER_PROPERTY, propertyList);
61                 addProperty(NAME_PROPERTY, propertyList);
62                 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
63         }
64
65         /**
66          * Returns a list of structural property descriptors for this node type.
67          * Clients must not modify the result.
68          * 
69          * @param apiLevel the API level; one of the
70          * <code>AST.JLS*</code> constants
71          * @return a list of property descriptors (element type: 
72          * {@link StructuralPropertyDescriptor})
73          * @since 3.0
74          */
75         public static List propertyDescriptors(int apiLevel) {
76                 return PROPERTY_DESCRIPTORS;
77         }
78                         
79         /**
80          * The optional qualifier; <code>null</code> for none; defaults to none.
81          */
82         private Name optionalQualifier = null;
83
84         /**
85          * The field; lazily initialized; defaults to an unspecified,
86          * but legal, simple field name.
87          */
88         private SimpleName fieldName = null;
89
90         /**
91          * Creates a new unparented node for a super field access expression owned
92          * by the given AST. By default, field name is an unspecified, but legal, 
93          * name, and there is no qualifier.
94          * <p>
95          * N.B. This constructor is package-private.
96          * </p>
97          * 
98          * @param ast the AST that is to own this node
99          */
100         SuperFieldAccess(AST ast) {
101                 super(ast);
102         }
103
104         /* (omit javadoc for this method)
105          * Method declared on ASTNode.
106          */
107         final List internalStructuralPropertiesForType(int apiLevel) {
108                 return propertyDescriptors(apiLevel);
109         }
110         
111         /* (omit javadoc for this method)
112          * Method declared on ASTNode.
113          */
114         final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
115                 if (property == QUALIFIER_PROPERTY) {
116                         if (get) {
117                                 return getQualifier();
118                         } else {
119                                 setQualifier((Name) child);
120                                 return null;
121                         }
122                 }
123                 if (property == NAME_PROPERTY) {
124                         if (get) {
125                                 return getName();
126                         } else {
127                                 setName((SimpleName) child);
128                                 return null;
129                         }
130                 }
131                 // allow default implementation to flag the error
132                 return super.internalGetSetChildProperty(property, get, child);
133         }
134         
135         /* (omit javadoc for this method)
136          * Method declared on ASTNode.
137          */
138         final int getNodeType0() {
139                 return SUPER_FIELD_ACCESS;
140         }
141
142         /* (omit javadoc for this method)
143          * Method declared on ASTNode.
144          */
145         ASTNode clone0(AST target) {
146                 SuperFieldAccess result = new SuperFieldAccess(target);
147                 result.setSourceRange(this.getStartPosition(), this.getLength());
148                 result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
149                 result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
150                 return result;
151         }
152
153         /* (omit javadoc for this method)
154          * Method declared on ASTNode.
155          */
156         final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
157                 // dispatch to correct overloaded match method
158                 return matcher.match(this, other);
159         }
160
161         /* (omit javadoc for this method)
162          * Method declared on ASTNode.
163          */
164         void accept0(ASTVisitor visitor) {
165                 boolean visitChildren = visitor.visit(this);
166                 if (visitChildren) {
167                         // visit children in normal left to right reading order
168                         acceptChild(visitor, getQualifier());
169                         acceptChild(visitor, getName());
170                 }
171                 visitor.endVisit(this);
172         }
173         
174         /**
175          * Returns the qualifier of this "super" field access expression, or 
176          * <code>null</code> if there is none.
177          * 
178          * @return the qualifier name node, or <code>null</code> if there is none
179          */ 
180         public Name getQualifier() {
181                 return this.optionalQualifier;
182         }
183         
184         /**
185          * Sets or clears the qualifier of this "super" field access expression.
186          * 
187          * @param name the qualifier name node, or <code>null</code> if 
188          *    there is none
189          * @exception IllegalArgumentException if:
190          * <ul>
191          * <li>the node belongs to a different AST</li>
192          * <li>the node already has a parent</li>
193          * </ul>
194          */ 
195         public void setQualifier(Name name) {
196                 ASTNode oldChild = this.optionalQualifier;
197                 preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
198                 this.optionalQualifier = name;
199                 postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
200         }
201
202         /**
203          * Returns the name of the field accessed in this "super" field access 
204          * expression.
205          * 
206          * @return the field name
207          */ 
208         public SimpleName getName() {
209                 if (this.fieldName == null) {
210                         // lazy init must be thread-safe for readers
211                         synchronized (this) {
212                                 if (this.fieldName == null) {
213                                         preLazyInit();
214                                         this.fieldName = new SimpleName(this.ast);
215                                         postLazyInit(this.fieldName, NAME_PROPERTY);
216                                 }
217                         }
218                 }
219                 return this.fieldName;
220         }
221
222         /**
223          * Resolves and returns the binding for the field accessed by this
224          * expression.
225          * <p>
226          * Note that bindings are generally unavailable unless requested when the
227          * AST is being built.
228          * </p>
229          *
230          * @return the variable binding, or <code>null</code> if the binding cannot
231          * be resolved
232          * @since 3.0
233          */
234         public IVariableBinding resolveFieldBinding() {
235                 return this.ast.getBindingResolver().resolveField(this);
236         }
237                 
238         /**
239          * Sets the name of the field accessed in this "super" field access 
240          * expression.
241          * 
242          * @param fieldName the field name
243          * @exception IllegalArgumentException if:
244          * <ul>
245          * <li>the node belongs to a different AST</li>
246          * <li>the node already has a parent</li>
247          * </ul>
248          */ 
249         public void setName(SimpleName fieldName) {
250                 if (fieldName == null) {
251                         throw new IllegalArgumentException();
252                 }
253                 ASTNode oldChild = this.fieldName;
254                 preReplaceChild(oldChild, fieldName, NAME_PROPERTY);
255                 this.fieldName = fieldName;
256                 postReplaceChild(oldChild, fieldName, NAME_PROPERTY);
257         }
258
259         /* (omit javadoc for this method)
260          * Method declared on ASTNode.
261          */
262         int memSize() {
263                 // treat Code as free
264                 return BASE_NODE_SIZE + 2 * 4;
265         }
266         
267         /* (omit javadoc for this method)
268          * Method declared on ASTNode.
269          */
270         int treeSize() {
271                 return 
272                         memSize()
273                         + (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
274                         + (this.fieldName == null ? 0 : getName().treeSize());
275         }
276 }
277