001: /*******************************************************************************
002: * Copyright (c) 2004, 2006 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.jdt.core.dom;
011:
012: import java.util.ArrayList;
013: import java.util.List;
014:
015: /**
016: * AST node for a member reference within a doc comment
017: * ({@link Javadoc}). The principal uses of these are in "@see" and "@link"
018: * tag elements, for references to field members (and occasionally to method
019: * and constructor members).
020: * <pre>
021: * MemberRef:
022: * [ Name ] <b>#</b> Identifier
023: * </pre>
024: *
025: * @see Javadoc
026: * @since 3.0
027: */
028: public class MemberRef extends ASTNode implements IDocElement {
029:
030: /**
031: * The "qualifier" structural property of this node type.
032: * @since 3.0
033: */
034: public static final ChildPropertyDescriptor QUALIFIER_PROPERTY = new ChildPropertyDescriptor(
035: MemberRef.class,
036: "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
037:
038: /**
039: * The "name" structural property of this node type.
040: * @since 3.0
041: */
042: public static final ChildPropertyDescriptor NAME_PROPERTY = new ChildPropertyDescriptor(
043: MemberRef.class,
044: "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
045:
046: /**
047: * A list of property descriptors (element type:
048: * {@link StructuralPropertyDescriptor}),
049: * or null if uninitialized.
050: */
051: private static final List PROPERTY_DESCRIPTORS;
052:
053: static {
054: List propertyList = new ArrayList(3);
055: createPropertyList(MemberRef.class, propertyList);
056: addProperty(QUALIFIER_PROPERTY, propertyList);
057: addProperty(NAME_PROPERTY, propertyList);
058: PROPERTY_DESCRIPTORS = reapPropertyList(propertyList);
059: }
060:
061: /**
062: * Returns a list of structural property descriptors for this node type.
063: * Clients must not modify the result.
064: *
065: * @param apiLevel the API level; one of the AST.JLS* constants
066: * @return a list of property descriptors (element type:
067: * {@link StructuralPropertyDescriptor})
068: * @since 3.0
069: */
070: public static List propertyDescriptors(int apiLevel) {
071: return PROPERTY_DESCRIPTORS;
072: }
073:
074: /**
075: * The optional qualifier; <code>null</code> for none; defaults to none.
076: */
077: private Name optionalQualifier = null;
078:
079: /**
080: * The member name; lazily initialized; defaults to a unspecified,
081: * legal Java method name.
082: */
083: private SimpleName memberName = null;
084:
085: /**
086: * Creates a new AST node for a member reference owned by the given
087: * AST. By default, the method reference is for a member with an
088: * unspecified, but legal, name; and no qualifier.
089: * <p>
090: * N.B. This constructor is package-private; all subclasses must be
091: * declared in the same package; clients are unable to declare
092: * additional subclasses.
093: * </p>
094: *
095: * @param ast the AST that is to own this node
096: */
097: MemberRef(AST ast) {
098: super (ast);
099: }
100:
101: /* (omit javadoc for this method)
102: * Method declared on ASTNode.
103: */
104: final List internalStructuralPropertiesForType(int apiLevel) {
105: return propertyDescriptors(apiLevel);
106: }
107:
108: /* (omit javadoc for this method)
109: * Method declared on ASTNode.
110: */
111: final ASTNode internalGetSetChildProperty(
112: ChildPropertyDescriptor property, boolean get, ASTNode child) {
113: if (property == QUALIFIER_PROPERTY) {
114: if (get) {
115: return getQualifier();
116: } else {
117: setQualifier((Name) child);
118: return null;
119: }
120: }
121: if (property == NAME_PROPERTY) {
122: if (get) {
123: return getName();
124: } else {
125: setName((SimpleName) child);
126: return null;
127: }
128: }
129: // allow default implementation to flag the error
130: return super .internalGetSetChildProperty(property, get, child);
131: }
132:
133: /* (omit javadoc for this method)
134: * Method declared on ASTNode.
135: */
136: final int getNodeType0() {
137: return MEMBER_REF;
138: }
139:
140: /* (omit javadoc for this method)
141: * Method declared on ASTNode.
142: */
143: ASTNode clone0(AST target) {
144: MemberRef result = new MemberRef(target);
145: result
146: .setSourceRange(this .getStartPosition(), this
147: .getLength());
148: result.setQualifier((Name) ASTNode.copySubtree(target,
149: getQualifier()));
150: result.setName((SimpleName) ASTNode.copySubtree(target,
151: getName()));
152: return result;
153: }
154:
155: /* (omit javadoc for this method)
156: * Method declared on ASTNode.
157: */
158: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
159: // dispatch to correct overloaded match method
160: return matcher.match(this , other);
161: }
162:
163: /* (omit javadoc for this method)
164: * Method declared on ASTNode.
165: */
166: void accept0(ASTVisitor visitor) {
167: boolean visitChildren = visitor.visit(this );
168: if (visitChildren) {
169: // visit children in normal left to right reading order
170: acceptChild(visitor, getQualifier());
171: acceptChild(visitor, getName());
172: }
173: visitor.endVisit(this );
174: }
175:
176: /**
177: * Returns the qualifier of this member reference, or
178: * <code>null</code> if there is none.
179: *
180: * @return the qualifier name node, or <code>null</code> if there is none
181: */
182: public Name getQualifier() {
183: return this .optionalQualifier;
184: }
185:
186: /**
187: * Sets or clears the qualifier of this member reference.
188: *
189: * @param name the qualifier name node, or <code>null</code> if
190: * there is none
191: * @exception IllegalArgumentException if:
192: * <ul>
193: * <li>the node belongs to a different AST</li>
194: * <li>the node already has a parent</li>
195: * </ul>
196: */
197: public void setQualifier(Name name) {
198: ASTNode oldChild = this .optionalQualifier;
199: preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
200: this .optionalQualifier = name;
201: postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
202: }
203:
204: /**
205: * Returns the name of the referenced member.
206: *
207: * @return the member name node
208: */
209: public SimpleName getName() {
210: if (this .memberName == null) {
211: // lazy init must be thread-safe for readers
212: synchronized (this ) {
213: if (this .memberName == null) {
214: preLazyInit();
215: this .memberName = new SimpleName(this .ast);
216: postLazyInit(this .memberName, NAME_PROPERTY);
217: }
218: }
219: }
220: return this .memberName;
221: }
222:
223: /**
224: * Sets the name of the referenced member to the given name.
225: *
226: * @param name the new member name node
227: * @exception IllegalArgumentException if:
228: * <ul>
229: * <li>the name is <code>null</code></li>
230: * <li>the node belongs to a different AST</li>
231: * <li>the node already has a parent</li>
232: * </ul>
233: */
234: public void setName(SimpleName name) {
235: if (name == null) {
236: throw new IllegalArgumentException();
237: }
238: ASTNode oldChild = this .memberName;
239: preReplaceChild(oldChild, name, NAME_PROPERTY);
240: this .memberName = name;
241: postReplaceChild(oldChild, name, NAME_PROPERTY);
242: }
243:
244: /**
245: * Resolves and returns the binding for the entity referred to by
246: * this member reference.
247: * <p>
248: * Note that bindings are generally unavailable unless requested when the
249: * AST is being built.
250: * </p>
251: *
252: * @return the binding, or <code>null</code> if the binding cannot be
253: * resolved
254: */
255: public final IBinding resolveBinding() {
256: return this .ast.getBindingResolver().resolveReference(this );
257: }
258:
259: /* (omit javadoc for this method)
260: * Method declared on ASTNode.
261: */
262: int memSize() {
263: return BASE_NODE_SIZE + 2 * 4;
264: }
265:
266: /* (omit javadoc for this method)
267: * Method declared on ASTNode.
268: */
269: int treeSize() {
270: return memSize()
271: + (this .optionalQualifier == null ? 0 : getQualifier()
272: .treeSize())
273: + (this .memberName == null ? 0 : getName().treeSize());
274: }
275: }
|