001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 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: * Simple or qualified "super" method invocation expression AST node type.
017: * For JLS2:
018: * <pre>
019: * SuperMethodInvocation:
020: * [ ClassName <b>.</b> ] <b>super</b> <b>.</b> Identifier
021: * <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
022: * </pre>
023: * For JLS3, type arguments are added:
024: * <pre>
025: * SuperMethodInvocation:
026: * [ ClassName <b>.</b> ] <b>super</b> <b>.</b>
027: * [ <b><</b> Type { <b>,</b> Type } <b>></b> ]
028: * Identifier <b>(</b> [ Expression { <b>,</b> Expression } ] <b>)</b>
029: * </pre>
030: *
031: * @since 2.0
032: */
033: public class SuperMethodInvocation extends Expression {
034:
035: /**
036: * The "qualifier" structural property of this node type.
037: * @since 3.0
038: */
039: public static final ChildPropertyDescriptor QUALIFIER_PROPERTY = new ChildPropertyDescriptor(
040: SuperMethodInvocation.class,
041: "qualifier", Name.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
042:
043: /**
044: * The "typeArguments" structural property of this node type (added in JLS3 API).
045: * @since 3.1
046: */
047: public static final ChildListPropertyDescriptor TYPE_ARGUMENTS_PROPERTY = new ChildListPropertyDescriptor(
048: SuperMethodInvocation.class,
049: "typeArguments", Type.class, NO_CYCLE_RISK); //$NON-NLS-1$
050:
051: /**
052: * The "name" structural property of this node type.
053: * @since 3.0
054: */
055: public static final ChildPropertyDescriptor NAME_PROPERTY = new ChildPropertyDescriptor(
056: SuperMethodInvocation.class,
057: "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
058:
059: /**
060: * The "arguments" structural property of this node type.
061: * @since 3.0
062: */
063: public static final ChildListPropertyDescriptor ARGUMENTS_PROPERTY = new ChildListPropertyDescriptor(
064: SuperMethodInvocation.class,
065: "arguments", Expression.class, CYCLE_RISK); //$NON-NLS-1$
066:
067: /**
068: * A list of property descriptors (element type:
069: * {@link StructuralPropertyDescriptor}),
070: * or null if uninitialized.
071: * @since 3.0
072: */
073: private static final List PROPERTY_DESCRIPTORS_2_0;
074:
075: /**
076: * A list of property descriptors (element type:
077: * {@link StructuralPropertyDescriptor}),
078: * or null if uninitialized.
079: * @since 3.1
080: */
081: private static final List PROPERTY_DESCRIPTORS_3_0;
082:
083: static {
084: List propertyList = new ArrayList(4);
085: createPropertyList(SuperMethodInvocation.class, propertyList);
086: addProperty(QUALIFIER_PROPERTY, propertyList);
087: addProperty(NAME_PROPERTY, propertyList);
088: addProperty(ARGUMENTS_PROPERTY, propertyList);
089: PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
090:
091: propertyList = new ArrayList(5);
092: createPropertyList(SuperMethodInvocation.class, propertyList);
093: addProperty(QUALIFIER_PROPERTY, propertyList);
094: addProperty(TYPE_ARGUMENTS_PROPERTY, propertyList);
095: addProperty(NAME_PROPERTY, propertyList);
096: addProperty(ARGUMENTS_PROPERTY, propertyList);
097: PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
098: }
099:
100: /**
101: * Returns a list of structural property descriptors for this node type.
102: * Clients must not modify the result.
103: *
104: * @param apiLevel the API level; one of the
105: * <code>AST.JLS*</code> constants
106:
107: * @return a list of property descriptors (element type:
108: * {@link StructuralPropertyDescriptor})
109: * @since 3.0
110: */
111: public static List propertyDescriptors(int apiLevel) {
112: if (apiLevel == AST.JLS2_INTERNAL) {
113: return PROPERTY_DESCRIPTORS_2_0;
114: } else {
115: return PROPERTY_DESCRIPTORS_3_0;
116: }
117: }
118:
119: /**
120: * The optional qualifier; <code>null</code> for none; defaults to none.
121: */
122: private Name optionalQualifier = null;
123:
124: /**
125: * The type arguments (element type: <code>Type</code>).
126: * Null in JLS2. Added in JLS3; defaults to an empty list
127: * (see constructor).
128: * @since 3.1
129: */
130: private ASTNode.NodeList typeArguments = null;
131:
132: /**
133: * The method name; lazily initialized; defaults to a unspecified,
134: * legal Java method name.
135: */
136: private SimpleName methodName = null;
137:
138: /**
139: * The list of argument expressions (element type:
140: * <code>Expression</code>). Defaults to an empty list.
141: */
142: private ASTNode.NodeList arguments = new ASTNode.NodeList(
143: ARGUMENTS_PROPERTY);
144:
145: /**
146: * Creates a new AST node for a "super" method invocation expression owned
147: * by the given AST. By default, no qualifier, no type arguments,
148: * an unspecified, but legal, method name, and an empty list of arguments.
149: *
150: * @param ast the AST that is to own this node
151: */
152: SuperMethodInvocation(AST ast) {
153: super (ast);
154: if (ast.apiLevel >= AST.JLS3) {
155: this .typeArguments = new ASTNode.NodeList(
156: TYPE_ARGUMENTS_PROPERTY);
157: }
158: }
159:
160: /* (omit javadoc for this method)
161: * Method declared on ASTNode.
162: */
163: final List internalStructuralPropertiesForType(int apiLevel) {
164: return propertyDescriptors(apiLevel);
165: }
166:
167: /* (omit javadoc for this method)
168: * Method declared on ASTNode.
169: */
170: final ASTNode internalGetSetChildProperty(
171: ChildPropertyDescriptor property, boolean get, ASTNode child) {
172: if (property == QUALIFIER_PROPERTY) {
173: if (get) {
174: return getQualifier();
175: } else {
176: setQualifier((Name) child);
177: return null;
178: }
179: }
180: if (property == NAME_PROPERTY) {
181: if (get) {
182: return getName();
183: } else {
184: setName((SimpleName) child);
185: return null;
186: }
187: }
188: // allow default implementation to flag the error
189: return super .internalGetSetChildProperty(property, get, child);
190: }
191:
192: /* (omit javadoc for this method)
193: * Method declared on ASTNode.
194: */
195: final List internalGetChildListProperty(
196: ChildListPropertyDescriptor property) {
197: if (property == ARGUMENTS_PROPERTY) {
198: return arguments();
199: }
200: if (property == TYPE_ARGUMENTS_PROPERTY) {
201: return typeArguments();
202: }
203: // allow default implementation to flag the error
204: return super .internalGetChildListProperty(property);
205: }
206:
207: /* (omit javadoc for this method)
208: * Method declared on ASTNode.
209: */
210: final int getNodeType0() {
211: return SUPER_METHOD_INVOCATION;
212: }
213:
214: /* (omit javadoc for this method)
215: * Method declared on ASTNode.
216: */
217: ASTNode clone0(AST target) {
218: SuperMethodInvocation result = new SuperMethodInvocation(target);
219: result
220: .setSourceRange(this .getStartPosition(), this
221: .getLength());
222: result.setName((SimpleName) getName().clone(target));
223: result.setQualifier((Name) ASTNode.copySubtree(target,
224: getQualifier()));
225: if (this .ast.apiLevel >= AST.JLS3) {
226: result.typeArguments().addAll(
227: ASTNode.copySubtrees(target, typeArguments()));
228: }
229: result.arguments().addAll(
230: ASTNode.copySubtrees(target, arguments()));
231: return result;
232: }
233:
234: /* (omit javadoc for this method)
235: * Method declared on ASTNode.
236: */
237: final boolean subtreeMatch0(ASTMatcher matcher, Object other) {
238: // dispatch to correct overloaded match method
239: return matcher.match(this , other);
240: }
241:
242: /* (omit javadoc for this method)
243: * Method declared on ASTNode.
244: */
245: void accept0(ASTVisitor visitor) {
246: boolean visitChildren = visitor.visit(this );
247: if (visitChildren) {
248: // visit children in normal left to right reading order
249: acceptChild(visitor, getQualifier());
250: if (this .ast.apiLevel >= AST.JLS3) {
251: acceptChildren(visitor, this .typeArguments);
252: }
253: acceptChild(visitor, getName());
254: acceptChildren(visitor, this .arguments);
255: }
256: visitor.endVisit(this );
257: }
258:
259: /**
260: * Returns the qualifier of this "super" method invocation expression, or
261: * <code>null</code> if there is none.
262: *
263: * @return the qualifier name node, or <code>null</code> if there is none
264: */
265: public Name getQualifier() {
266: return this .optionalQualifier;
267: }
268:
269: /**
270: * Returns true if the resolved return type has been inferred from the assignment context (JLS3 15.12.2.8), false otherwise.
271: * <p>
272: * This information is available only when bindings are requested when the AST is being built
273: * </p>.
274: *
275: * @return true if the resolved return type has been inferred from the assignment context (JLS3 15.12.2.8), false otherwise
276: * @since 3.3
277: */
278: public boolean isResolvedTypeInferredFromExpectedType() {
279: return this .ast.getBindingResolver()
280: .isResolvedTypeInferredFromExpectedType(this );
281: }
282:
283: /**
284: * Sets or clears the qualifier of this "super" method invocation expression.
285: *
286: * @param name the qualifier name node, or <code>null</code> if
287: * there is none
288: * @exception IllegalArgumentException if:
289: * <ul>
290: * <li>the node belongs to a different AST</li>
291: * <li>the node already has a parent</li>
292: * </ul>
293: */
294: public void setQualifier(Name name) {
295: ASTNode oldChild = this .optionalQualifier;
296: preReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
297: this .optionalQualifier = name;
298: postReplaceChild(oldChild, name, QUALIFIER_PROPERTY);
299: }
300:
301: /**
302: * Returns the live ordered list of type arguments of this method
303: * invocation (added in JLS3 API).
304: *
305: * @return the live list of type arguments
306: * (element type: <code>Type</code>)
307: * @exception UnsupportedOperationException if this operation is used in
308: * a JLS2 AST
309: * @since 3.1
310: */
311: public List typeArguments() {
312: // more efficient than just calling unsupportedIn2() to check
313: if (this .typeArguments == null) {
314: unsupportedIn2();
315: }
316: return this .typeArguments;
317: }
318:
319: /**
320: * Returns the name of the method invoked in this expression.
321: *
322: * @return the method name node
323: */
324: public SimpleName getName() {
325: if (this .methodName == null) {
326: // lazy init must be thread-safe for readers
327: synchronized (this ) {
328: if (this .methodName == null) {
329: preLazyInit();
330: this .methodName = new SimpleName(this .ast);
331: postLazyInit(this .methodName, NAME_PROPERTY);
332: }
333: }
334: }
335: return this .methodName;
336: }
337:
338: /**
339: * Sets the name of the method invoked in this expression to the
340: * given name.
341: *
342: * @param name the new method name
343: * @exception IllegalArgumentException if:
344: * <ul>
345: * <li>the node belongs to a different AST</li>
346: * <li>the node already has a parent</li>
347: * </ul>
348: */
349: public void setName(SimpleName name) {
350: if (name == null) {
351: throw new IllegalArgumentException();
352: }
353: ASTNode oldChild = this .methodName;
354: preReplaceChild(oldChild, name, NAME_PROPERTY);
355: this .methodName = name;
356: postReplaceChild(oldChild, name, NAME_PROPERTY);
357: }
358:
359: /**
360: * Returns the live ordered list of argument expressions in this
361: * "super" method invocation expression.
362: *
363: * @return the live list of argument expressions
364: * (element type: <code>Expression</code>)
365: */
366: public List arguments() {
367: return this .arguments;
368: }
369:
370: /**
371: * Resolves and returns the binding for the method invoked by this
372: * expression.
373: * <p>
374: * Note that bindings are generally unavailable unless requested when the
375: * AST is being built.
376: * </p>
377: *
378: * @return the method binding, or <code>null</code> if the binding cannot
379: * be resolved
380: * @since 2.1
381: */
382: public IMethodBinding resolveMethodBinding() {
383: return this .ast.getBindingResolver().resolveMethod(this );
384: }
385:
386: /* (omit javadoc for this method)
387: * Method declared on ASTNode.
388: */
389: int memSize() {
390: // treat Code as free
391: return BASE_NODE_SIZE + 4 * 4;
392: }
393:
394: /* (omit javadoc for this method)
395: * Method declared on ASTNode.
396: */
397: int treeSize() {
398: return memSize()
399: + (this .optionalQualifier == null ? 0 : getQualifier()
400: .treeSize())
401: + (this .typeArguments == null ? 0 : this .typeArguments
402: .listSize())
403: + (this .methodName == null ? 0 : getName().treeSize())
404: + (this .arguments == null ? 0 : this.arguments
405: .listSize());
406: }
407: }
|