1 /*******************************************************************************
2 * Copyright (c) 2004, 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 * AST node for a member reference within a doc comment
19 * ({@link Javadoc}). The principal uses of these are in "@see" and "@link"
20 * tag elements, for references to field members (and occasionally to method
21 * and constructor members).
24 * [ Name ] <b>#</b> Identifier
29 * @noinstantiate This class is not intended to be instantiated by clients.
31 public class MemberRef extends ASTNode implements IDocElement {
34 * The "qualifier" structural property of this node type.
37 public static final ChildPropertyDescriptor QUALIFIER_PROPERTY =
38 new ChildPropertyDescriptor(MemberRef.class, "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
41 * The "name" structural property of this node type.
44 public static final ChildPropertyDescriptor NAME_PROPERTY =
45 new ChildPropertyDescriptor(MemberRef.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
48 * A list of property descriptors (element type:
49 * {@link StructuralPropertyDescriptor}),
50 * or null if uninitialized.
52 private static final List PROPERTY_DESCRIPTORS;
55 List propertyList = new ArrayList(3);
56 createPropertyList(MemberRef.class, propertyList);
57 addProperty(QUALIFIER_PROPERTY, propertyList);
58 addProperty(NAME_PROPERTY, propertyList);
59 PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
63 * Returns a list of structural property descriptors for this node type.
64 * Clients must not modify the result.
66 * @param apiLevel the API level; one of the AST.JLS* constants
67 * @return a list of property descriptors (element type:
68 * {@link StructuralPropertyDescriptor})
71 public static List propertyDescriptors(int apiLevel) {
72 return PROPERTY_DESCRIPTORS;
76 * The optional qualifier; <code>null</code> for none; defaults to none.
78 private Name optionalQualifier = null;
81 * The member name; lazily initialized; defaults to a unspecified,
82 * legal Java method name.
84 private SimpleName memberName = null;
87 * Creates a new AST node for a member reference owned by the given
88 * AST. By default, the method reference is for a member with an
89 * unspecified, but legal, name; and no qualifier.
91 * N.B. This constructor is package-private; all subclasses must be
92 * declared in the same package; clients are unable to declare
93 * additional subclasses.
96 * @param ast the AST that is to own this node
102 /* (omit javadoc for this method)
103 * Method declared on ASTNode.
105 final List internalStructuralPropertiesForType(int apiLevel) {
106 return propertyDescriptors(apiLevel);
109 /* (omit javadoc for this method)
110 * Method declared on ASTNode.
112 final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
113 if (property == QUALIFIER_PROPERTY) {
115 return getQualifier();
117 setQualifier((Name) child);
121 if (property == NAME_PROPERTY) {
125 setName((SimpleName) child);
129 // allow default implementation to flag the error
130 return super.internalGetSetChildProperty(property, get, child);
133 /* (omit javadoc for this method)
134 * Method declared on ASTNode.
136 final int getNodeType0() {
140 /* (omit javadoc for this method)
141 * Method declared on ASTNode.
143 ASTNode clone0(AST target) {
144 MemberRef result = new MemberRef(target);
145 result.setSourceRange(this.getStartPosition(), this.getLength());
146 result.setQualifier((Name) ASTNode.copySubtree(target, getQualifier()));
147 result.setName((SimpleName) ASTNode.copySubtree(target, getName()));
151 /* (omit javadoc for this method)
152 * Method declared on ASTNode.
154 final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
155 // dispatch to correct overloaded match method
156 return matcher.match(this, other);
159 /* (omit javadoc for this method)
160 * Method declared on ASTNode.
162 void accept0(ASTVisitor visitor) {
163 boolean visitChildren = visitor.visit(this);
165 // visit children in normal left to right reading order
166 acceptChild(visitor, getQualifier());
167 acceptChild(visitor, getName());
169 visitor.endVisit(this);
173 * Returns the qualifier of this member reference, or
174 * <code>null</code> if there is none.
176 * @return the qualifier name node, or <code>null</code> if there is none
178 public Name getQualifier() {
179 return this.optionalQualifier;
183 * Sets or clears the qualifier of this member reference.
185 * @param name the qualifier name node, or <code>null</code> if
187 * @exception IllegalArgumentException if:
189 * <li>the node belongs to a different AST</li>
190 * <li>the node already has a parent</li>
193 public void setQualifier(Name name) {
194 ASTNode oldChild = this.optionalQualifier;
195 preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
196 this.optionalQualifier = name;
197 postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
201 * Returns the name of the referenced member.
203 * @return the member name node
205 public SimpleName getName() {
206 if (this.memberName == null) {
207 // lazy init must be thread-safe for readers
208 synchronized (this) {
209 if (this.memberName == null) {
211 this.memberName = new SimpleName(this.ast);
212 postLazyInit(this.memberName, NAME_PROPERTY);
216 return this.memberName;
220 * Sets the name of the referenced member to the given name.
222 * @param name the new member name node
223 * @exception IllegalArgumentException if:
225 * <li>the name is <code>null</code></li>
226 * <li>the node belongs to a different AST</li>
227 * <li>the node already has a parent</li>
230 public void setName(SimpleName name) {
232 throw new IllegalArgumentException();
234 ASTNode oldChild = this.memberName;
235 preReplaceChild(oldChild, name, NAME_PROPERTY);
236 this.memberName = name;
237 postReplaceChild(oldChild, name, NAME_PROPERTY);
241 * Resolves and returns the binding for the entity referred to by
242 * this member reference.
244 * Note that bindings are generally unavailable unless requested when the
245 * AST is being built.
248 * @return the binding, or <code>null</code> if the binding cannot be
251 public final IBinding resolveBinding() {
252 return this.ast.getBindingResolver().resolveReference(this);
255 /* (omit javadoc for this method)
256 * Method declared on ASTNode.
259 return BASE_NODE_SIZE + 2 * 4;
262 /* (omit javadoc for this method)
263 * Method declared on ASTNode.
268 + (this.optionalQualifier == null ? 0 : getQualifier().treeSize())
269 + (this.memberName == null ? 0 : getName().treeSize());