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 method or constructor reference within a doc comment
017: * ({@link Javadoc}). The principal uses of these are in "@see" and "@link"
018: * tag elements, for references to method and constructor members.
019: * <pre>
020: * MethodRef:
021: * [ Name ] <b>#</b> Identifier
022: * <b>(</b> [ MethodRefParameter | { <b>,</b> MethodRefParameter } ] <b>)</b>
023: * </pre>
024: *
025: * @see Javadoc
026: * @since 3.0
027: */
028: public class MethodRef 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: MethodRef.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: MethodRef.class,
044: "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
045:
046: /**
047: * The "parameters" structural property of this node type.
048: * @since 3.0
049: */
050: public static final ChildListPropertyDescriptor PARAMETERS_PROPERTY = new ChildListPropertyDescriptor(
051: MethodRef.class,
052: "parameters", MethodRefParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
053:
054: /**
055: * A list of property descriptors (element type:
056: * {@link StructuralPropertyDescriptor}),
057: * or null if uninitialized.
058: */
059: private static final List PROPERTY_DESCRIPTORS;
060:
061: static {
062: List properyList = new ArrayList(4);
063: createPropertyList(MethodRef.class, properyList);
064: addProperty(QUALIFIER_PROPERTY, properyList);
065: addProperty(NAME_PROPERTY, properyList);
066: addProperty(PARAMETERS_PROPERTY, properyList);
067: PROPERTY_DESCRIPTORS = reapPropertyList(properyList);
068: }
069:
070: /**
071: * Returns a list of structural property descriptors for this node type.
072: * Clients must not modify the result.
073: *
074: * @param apiLevel the API level; one of the AST.JLS* constants
075: * @return a list of property descriptors (element type:
076: * {@link StructuralPropertyDescriptor})
077: * @since 3.0
078: */
079: public static List propertyDescriptors(int apiLevel) {
080: return PROPERTY_DESCRIPTORS;
081: }
082:
083: /**
084: * The optional qualifier; <code>null</code> for none; defaults to none.
085: */
086: private Name optionalQualifier = null;
087:
088: /**
089: * The method name; lazily initialized; defaults to a unspecified,
090: * legal Java method name.
091: */
092: private SimpleName methodName = null;
093:
094: /**
095: * The parameter declarations
096: * (element type: <code>MethodRefParameter</code>).
097: * Defaults to an empty list.
098: */
099: private ASTNode.NodeList parameters = new ASTNode.NodeList(
100: PARAMETERS_PROPERTY);
101:
102: /**
103: * Creates a new AST node for a method reference owned by the given
104: * AST. By default, the method reference is for a method with an
105: * unspecified, but legal, name; no qualifier; and an empty parameter
106: * list.
107: * <p>
108: * N.B. This constructor is package-private; all subclasses must be
109: * declared in the same package; clients are unable to declare
110: * additional subclasses.
111: * </p>
112: *
113: * @param ast the AST that is to own this node
114: */
115: MethodRef(AST ast) {
116: super (ast);
117: }
118:
119: /* (omit javadoc for this method)
120: * Method declared on ASTNode.
121: */
122: final List internalStructuralPropertiesForType(int apiLevel) {
123: return propertyDescriptors(apiLevel);
124: }
125:
126: /* (omit javadoc for this method)
127: * Method declared on ASTNode.
128: */
129: final ASTNode internalGetSetChildProperty(
130: ChildPropertyDescriptor property, boolean get, ASTNode child) {
131: if (property == QUALIFIER_PROPERTY) {
132: if (get) {
133: return getQualifier();
134: } else {
135: setQualifier((Name) child);
136: return null;
137: }
138: }
139: if (property == NAME_PROPERTY) {
140: if (get) {
141: return getName();
142: } else {
143: setName((SimpleName) child);
144: return null;
145: }
146: }
147: // allow default implementation to flag the error
148: return super .internalGetSetChildProperty(property, get, child);
149: }
150:
151: /* (omit javadoc for this method)
152: * Method declared on ASTNode.
153: */
154: final List internalGetChildListProperty(
155: ChildListPropertyDescriptor property) {
156: if (property == PARAMETERS_PROPERTY) {
157: return parameters();
158: }
159: // allow default implementation to flag the error
160: return super .internalGetChildListProperty(property);
161: }
162:
163: /* (omit javadoc for this method)
164: * Method declared on ASTNode.
165: */
166: final int getNodeType0() {
167: return METHOD_REF;
168: }
169:
170: /* (omit javadoc for this method)
171: * Method declared on ASTNode.
172: */
173: ASTNode clone0(AST target) {
174: MethodRef result = new MethodRef(target);
175: result
176: .setSourceRange(this .getStartPosition(), this
177: .getLength());
178: result.setQualifier((Name) ASTNode.copySubtree(target,
179: getQualifier()));
180: result.setName((SimpleName) ASTNode.copySubtree(target,
181: getName()));
182: result.parameters().addAll(
183: ASTNode.copySubtrees(target, parameters()));
184: return result;
185: }
186:
187: /* (omit javadoc for this method)
188: * Method declared on ASTNode.
189: */
190: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
191: // dispatch to correct overloaded match method
192: return matcher.match(this , other);
193: }
194:
195: /* (omit javadoc for this method)
196: * Method declared on ASTNode.
197: */
198: void accept0(ASTVisitor visitor) {
199: boolean visitChildren = visitor.visit(this );
200: if (visitChildren) {
201: // visit children in normal left to right reading order
202: acceptChild(visitor, getQualifier());
203: acceptChild(visitor, getName());
204: acceptChildren(visitor, this .parameters);
205: }
206: visitor.endVisit(this );
207: }
208:
209: /**
210: * Returns the qualifier of this method reference, or
211: * <code>null</code> if there is none.
212: *
213: * @return the qualifier name node, or <code>null</code> if there is none
214: */
215: public Name getQualifier() {
216: return this .optionalQualifier;
217: }
218:
219: /**
220: * Sets or clears the qualifier of this method reference.
221: *
222: * @param name the qualifier name node, or <code>null</code> if
223: * there is none
224: * @exception IllegalArgumentException if:
225: * <ul>
226: * <li>the node belongs to a different AST</li>
227: * <li>the node already has a parent</li>
228: * </ul>
229: */
230: public void setQualifier(Name name) {
231: ASTNode oldChild = this .optionalQualifier;
232: preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
233: this .optionalQualifier = name;
234: postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
235: }
236:
237: /**
238: * Returns the name of the referenced method or constructor.
239: *
240: * @return the method or constructor name node
241: */
242: public SimpleName getName() {
243: if (this .methodName == null) {
244: // lazy init must be thread-safe for readers
245: synchronized (this ) {
246: if (this .methodName == null) {
247: preLazyInit();
248: this .methodName = new SimpleName(this .ast);
249: postLazyInit(this .methodName, NAME_PROPERTY);
250: }
251: }
252: }
253: return this .methodName;
254: }
255:
256: /**
257: * Sets the name of the referenced method or constructor to the
258: * given name.
259: *
260: * @param name the new method or constructor name node
261: * @exception IllegalArgumentException if:
262: * <ul>
263: * <li>the name is <code>null</code></li>
264: * <li>the node belongs to a different AST</li>
265: * <li>the node already has a parent</li>
266: * </ul>
267: */
268: public void setName(SimpleName name) {
269: if (name == null) {
270: throw new IllegalArgumentException();
271: }
272: ASTNode oldChild = this .methodName;
273: preReplaceChild(oldChild, name, NAME_PROPERTY);
274: this .methodName = name;
275: postReplaceChild(oldChild, name, NAME_PROPERTY);
276: }
277:
278: /**
279: * Returns the live ordered list of method parameter references for this
280: * method reference.
281: *
282: * @return the live list of method parameter references
283: * (element type: <code>MethodRefParameter</code>)
284: */
285: public List parameters() {
286: return this .parameters;
287: }
288:
289: /**
290: * Resolves and returns the binding for the entity referred to by
291: * this method reference.
292: * <p>
293: * Note that bindings are generally unavailable unless requested when the
294: * AST is being built.
295: * </p>
296: *
297: * @return the binding, or <code>null</code> if the binding cannot be
298: * resolved
299: */
300: public final IBinding resolveBinding() {
301: return this .ast.getBindingResolver().resolveReference(this );
302: }
303:
304: /* (omit javadoc for this method)
305: * Method declared on ASTNode.
306: */
307: int memSize() {
308: return BASE_NODE_SIZE + 3 * 4;
309: }
310:
311: /* (omit javadoc for this method)
312: * Method declared on ASTNode.
313: */
314: int treeSize() {
315: return memSize()
316: + (this .optionalQualifier == null ? 0 : getQualifier()
317: .treeSize())
318: + (this .methodName == null ? 0 : getName().treeSize())
319: + this.parameters.listSize();
320: }
321: }
|