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 * Simple or qualified "super" field access expression AST node type.
22 * [ ClassName <b>.</b> ] <b>super</b> <b>.</b> Identifier
26 * See <code>FieldAccess</code> for guidelines on handling other expressions
27 * that resemble qualified names.
32 * @noinstantiate This class is not intended to be instantiated by clients.
34 public class SuperFieldAccess extends Expression {
37 * The "qualifier" structural property of this node type.
40 public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
41 new ChildPropertyDescriptor(SuperFieldAccess.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
44 * The "name" structural property of this node type.
47 public static final ChildPropertyDescriptor NAME_PROPERTY =
48 new ChildPropertyDescriptor(SuperFieldAccess.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
51 * A list of property descriptors (element type:
52 * {@link StructuralPropertyDescriptor}),
53 * or null if uninitialized.
55 private static final List PROPERTY_DESCRIPTORS;
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);
66 * Returns a list of structural property descriptors for this node type.
67 * Clients must not modify the result.
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})
75 public static List propertyDescriptors(int apiLevel) {
76 return PROPERTY_DESCRIPTORS;
80 * The optional qualifier; <code>null</code> for none; defaults to none.
82 private Name optionalQualifier = null;
85 * The field; lazily initialized; defaults to an unspecified,
86 * but legal, simple field name.
88 private SimpleName fieldName = null;
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.
95 * N.B. This constructor is package-private.
98 * @param ast the AST that is to own this node
100 SuperFieldAccess(AST ast) {
104 /* (omit javadoc for this method)
105 * Method declared on ASTNode.
107 final List internalStructuralPropertiesForType(int apiLevel) {
108 return propertyDescriptors(apiLevel);
111 /* (omit javadoc for this method)
112 * Method declared on ASTNode.
114 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
115 if (property == QUALIFIER_PROPERTY) {
117 return getQualifier();
119 setQualifier((Name) child);
123 if (property == NAME_PROPERTY) {
127 setName((SimpleName) child);
131 // allow default implementation to flag the error
132 return super.internalGetSetChildProperty(property, get, child);
135 /* (omit javadoc for this method)
136 * Method declared on ASTNode.
138 final int getNodeType0() {
139 return SUPER_FIELD_ACCESS;
142 /* (omit javadoc for this method)
143 * Method declared on ASTNode.
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()));
153 /* (omit javadoc for this method)
154 * Method declared on ASTNode.
156 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
157 // dispatch to correct overloaded match method
158 return matcher.match(this, other);
161 /* (omit javadoc for this method)
162 * Method declared on ASTNode.
164 void accept0(ASTVisitor visitor) {
165 boolean visitChildren = visitor.visit(this);
167 // visit children in normal left to right reading order
168 acceptChild(visitor, getQualifier());
169 acceptChild(visitor, getName());
171 visitor.endVisit(this);
175 * Returns the qualifier of this "super" field access expression, or
176 * <code>null</code> if there is none.
178 * @return the qualifier name node, or <code>null</code> if there is none
180 public Name getQualifier() {
181 return this.optionalQualifier;
185 * Sets or clears the qualifier of this "super" field access expression.
187 * @param name the qualifier name node, or <code>null</code> if
189 * @exception IllegalArgumentException if:
191 * <li>the node belongs to a different AST</li>
192 * <li>the node already has a parent</li>
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);
203 * Returns the name of the field accessed in this "super" field access
206 * @return the field name
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) {
214 this.fieldName = new SimpleName(this.ast);
215 postLazyInit(this.fieldName, NAME_PROPERTY);
219 return this.fieldName;
223 * Resolves and returns the binding for the field accessed by this
226 * Note that bindings are generally unavailable unless requested when the
227 * AST is being built.
230 * @return the variable binding, or <code>null</code> if the binding cannot
234 public IVariableBinding resolveFieldBinding() {
235 return this.ast.getBindingResolver().resolveField(this);
239 * Sets the name of the field accessed in this "super" field access
242 * @param fieldName the field name
243 * @exception IllegalArgumentException if:
245 * <li>the node belongs to a different AST</li>
246 * <li>the node already has a parent</li>
249 public void setName(SimpleName fieldName) {
250 if (fieldName == null) {
251 throw new IllegalArgumentException();
253 ASTNode oldChild = this.fieldName;
254 preReplaceChild(oldChild, fieldName, NAME_PROPERTY);
255 this.fieldName = fieldName;
256 postReplaceChild(oldChild, fieldName, NAME_PROPERTY);
259 /* (omit javadoc for this method)
260 * Method declared on ASTNode.
263 // treat Code as free
264 return BASE_NODE_SIZE + 2 * 4;
267 /* (omit javadoc for this method)
268 * Method declared on ASTNode.
273 + (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
274 + (this.fieldName == null ? 0 : getName().treeSize());