KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdt > core > dom > MethodDeclaration


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11
12 package org.eclipse.jdt.core.dom;
13
14 import java.util.ArrayList JavaDoc;
15 import java.util.List JavaDoc;
16
17 /**
18  * Method declaration AST node type. A method declaration
19  * is the union of a method declaration and a constructor declaration.
20  * For JLS2:
21  * <pre>
22  * MethodDeclaration:
23  * [ Javadoc ] { Modifier } ( Type | <b>void</b> ) Identifier <b>(</b>
24  * [ FormalParameter
25  * { <b>,</b> FormalParameter } ] <b>)</b> {<b>[</b> <b>]</b> }
26  * [ <b>throws</b> TypeName { <b>,</b> TypeName } ] ( Block | <b>;</b> )
27  * ConstructorDeclaration:
28  * [ Javadoc ] { Modifier } Identifier <b>(</b>
29  * [ FormalParameter
30  * { <b>,</b> FormalParameter } ] <b>)</b>
31  * [<b>throws</b> TypeName { <b>,</b> TypeName } ] Block
32  * </pre>
33  * For JLS3, type parameters and reified modifiers
34  * (and annotations) were added:
35  * <pre>
36  * MethodDeclaration:
37  * [ Javadoc ] { ExtendedModifier }
38  * [ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ]
39  * ( Type | <b>void</b> ) Identifier <b>(</b>
40  * [ FormalParameter
41  * { <b>,</b> FormalParameter } ] <b>)</b> {<b>[</b> <b>]</b> }
42  * [ <b>throws</b> TypeName { <b>,</b> TypeName } ] ( Block | <b>;</b> )
43  * ConstructorDeclaration:
44  * [ Javadoc ] { ExtendedModifier }
45  * [ <b>&lt;</b> TypeParameter { <b>,</b> TypeParameter } <b>&gt;</b> ]
46  * Identifier <b>(</b>
47  * [ FormalParameter
48  * { <b>,</b> FormalParameter } ] <b>)</b>
49  * [<b>throws</b> TypeName { <b>,</b> TypeName } ] Block
50  * </pre>
51  * <p>
52  * When a Javadoc comment is present, the source
53  * range begins with the first character of the "/**" comment delimiter.
54  * When there is no Javadoc comment, the source range begins with the first
55  * character of the first modifier keyword (if modifiers), or the
56  * first character of the "&lt;" token (method, no modifiers, type parameters),
57  * or the first character of the return type (method, no modifiers, no type
58  * parameters), or the first character of the identifier (constructor,
59  * no modifiers). The source range extends through the last character of the
60  * ";" token (if no body), or the last character of the block (if body).
61  * </p>
62  *
63  * @since 2.0
64  */

65 public class MethodDeclaration extends BodyDeclaration {
66     
67     /**
68      * The "javadoc" structural property of this node type.
69      * @since 3.0
70      */

71     public static final ChildPropertyDescriptor JAVADOC_PROPERTY =
72         internalJavadocPropertyFactory(MethodDeclaration.class);
73
74     /**
75      * The "modifiers" structural property of this node type (JLS2 API only).
76      * @since 3.0
77      */

78     public static final SimplePropertyDescriptor MODIFIERS_PROPERTY =
79         internalModifiersPropertyFactory(MethodDeclaration.class);
80     
81     /**
82      * The "modifiers" structural property of this node type (added in JLS3 API).
83      * @since 3.1
84      */

85     public static final ChildListPropertyDescriptor MODIFIERS2_PROPERTY =
86         internalModifiers2PropertyFactory(MethodDeclaration.class);
87     
88     /**
89      * The "constructor" structural property of this node type.
90      * @since 3.0
91      */

92     public static final SimplePropertyDescriptor CONSTRUCTOR_PROPERTY =
93         new SimplePropertyDescriptor(MethodDeclaration.class, "constructor", boolean.class, MANDATORY); //$NON-NLS-1$
94

95     /**
96      * The "name" structural property of this node type.
97      * @since 3.0
98      */

99     public static final ChildPropertyDescriptor NAME_PROPERTY =
100         new ChildPropertyDescriptor(MethodDeclaration.class, "name", SimpleName.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
101

102     /**
103      * The "returnType" structural property of this node type (JLS2 API only).
104      * @since 3.0
105      */

106     public static final ChildPropertyDescriptor RETURN_TYPE_PROPERTY =
107         new ChildPropertyDescriptor(MethodDeclaration.class, "returnType", Type.class, MANDATORY, NO_CYCLE_RISK); //$NON-NLS-1$
108

109     /**
110      * The "returnType2" structural property of this node type (added in JLS3 API).
111      * @since 3.1
112      */

113     public static final ChildPropertyDescriptor RETURN_TYPE2_PROPERTY =
114         new ChildPropertyDescriptor(MethodDeclaration.class, "returnType2", Type.class, OPTIONAL, NO_CYCLE_RISK); //$NON-NLS-1$
115

116     /**
117      * The "extraDimensions" structural property of this node type.
118      * @since 3.0
119      */

120     public static final SimplePropertyDescriptor EXTRA_DIMENSIONS_PROPERTY =
121         new SimplePropertyDescriptor(MethodDeclaration.class, "extraDimensions", int.class, MANDATORY); //$NON-NLS-1$
122

123     /**
124      * The "typeParameters" structural property of this node type (added in JLS3 API).
125      * @since 3.1
126      */

127     public static final ChildListPropertyDescriptor TYPE_PARAMETERS_PROPERTY =
128         new ChildListPropertyDescriptor(MethodDeclaration.class, "typeParameters", TypeParameter.class, NO_CYCLE_RISK); //$NON-NLS-1$
129

130     /**
131      * The "parameters" structural property of this node type).
132      * @since 3.0
133      */

134     public static final ChildListPropertyDescriptor PARAMETERS_PROPERTY =
135         new ChildListPropertyDescriptor(MethodDeclaration.class, "parameters", SingleVariableDeclaration.class, CYCLE_RISK); //$NON-NLS-1$
136

137     /**
138      * The "thrownExceptions" structural property of this node type).
139      * @since 3.0
140      */

141     public static final ChildListPropertyDescriptor THROWN_EXCEPTIONS_PROPERTY =
142         new ChildListPropertyDescriptor(MethodDeclaration.class, "thrownExceptions", Name.class, NO_CYCLE_RISK); //$NON-NLS-1$
143

144     /**
145      * The "body" structural property of this node type.
146      * @since 3.0
147      */

148     public static final ChildPropertyDescriptor BODY_PROPERTY =
149         new ChildPropertyDescriptor(MethodDeclaration.class, "body", Block.class, OPTIONAL, CYCLE_RISK); //$NON-NLS-1$
150

151     /**
152      * A list of property descriptors (element type:
153      * {@link StructuralPropertyDescriptor}),
154      * or null if uninitialized.
155      * @since 3.0
156      */

157     private static final List JavaDoc PROPERTY_DESCRIPTORS_2_0;
158     
159     /**
160      * A list of property descriptors (element type:
161      * {@link StructuralPropertyDescriptor}),
162      * or null if uninitialized.
163      * @since 3.1
164      */

165     private static final List JavaDoc PROPERTY_DESCRIPTORS_3_0;
166     
167     static {
168         List JavaDoc propertyList = new ArrayList JavaDoc(10);
169         createPropertyList(MethodDeclaration.class, propertyList);
170         addProperty(JAVADOC_PROPERTY, propertyList);
171         addProperty(MODIFIERS_PROPERTY, propertyList);
172         addProperty(CONSTRUCTOR_PROPERTY, propertyList);
173         addProperty(RETURN_TYPE_PROPERTY, propertyList);
174         addProperty(NAME_PROPERTY, propertyList);
175         addProperty(PARAMETERS_PROPERTY, propertyList);
176         addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
177         addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList);
178         addProperty(BODY_PROPERTY, propertyList);
179         PROPERTY_DESCRIPTORS_2_0 = reapPropertyList(propertyList);
180         
181         propertyList = new ArrayList JavaDoc(11);
182         createPropertyList(MethodDeclaration.class, propertyList);
183         addProperty(JAVADOC_PROPERTY, propertyList);
184         addProperty(MODIFIERS2_PROPERTY, propertyList);
185         addProperty(CONSTRUCTOR_PROPERTY, propertyList);
186         addProperty(TYPE_PARAMETERS_PROPERTY, propertyList);
187         addProperty(RETURN_TYPE2_PROPERTY, propertyList);
188         addProperty(NAME_PROPERTY, propertyList);
189         addProperty(PARAMETERS_PROPERTY, propertyList);
190         addProperty(EXTRA_DIMENSIONS_PROPERTY, propertyList);
191         addProperty(THROWN_EXCEPTIONS_PROPERTY, propertyList);
192         addProperty(BODY_PROPERTY, propertyList);
193         PROPERTY_DESCRIPTORS_3_0 = reapPropertyList(propertyList);
194     }
195
196     /**
197      * Returns a list of structural property descriptors for this node type.
198      * Clients must not modify the result.
199      *
200      * @param apiLevel the API level; one of the AST.JLS* constants
201      * @return a list of property descriptors (element type:
202      * {@link StructuralPropertyDescriptor})
203      * @since 3.0
204      */

205     public static List JavaDoc propertyDescriptors(int apiLevel) {
206         if (apiLevel == AST.JLS2_INTERNAL) {
207             return PROPERTY_DESCRIPTORS_2_0;
208         } else {
209             return PROPERTY_DESCRIPTORS_3_0;
210         }
211     }
212             
213     /**
214      * <code>true</code> for a constructor, <code>false</code> for a method.
215      * Defaults to method.
216      */

217     private boolean isConstructor = false;
218     
219     /**
220      * The method name; lazily initialized; defaults to an unspecified,
221      * legal Java identifier.
222      */

223     private SimpleName methodName = null;
224
225     /**
226      * The parameter declarations
227      * (element type: <code>SingleVariableDeclaration</code>).
228      * Defaults to an empty list.
229      */

230     private ASTNode.NodeList parameters =
231         new ASTNode.NodeList(PARAMETERS_PROPERTY);
232     
233     /**
234      * The return type.
235      * JLS2 behevior: lazily initialized; defaults to void.
236      * JLS3 behavior; lazily initialized; defaults to void; null allowed.
237      * Note that this field is ignored for constructor declarations.
238      */

239     private Type returnType = null;
240     
241     /**
242      * Indicated whether the return type has been initialized.
243      * @since 3.1
244      */

245     private boolean returnType2Initialized = false;
246     
247     /**
248      * The type paramters (element type: <code>TypeParameter</code>).
249      * Null in JLS2. Added in JLS3; defaults to an empty list
250      * (see constructor).
251      * @since 3.1
252      */

253     private ASTNode.NodeList typeParameters = null;
254
255     /**
256      * The number of array dimensions that appear after the parameters, rather
257      * than after the return type itself; defaults to 0.
258      *
259      * @since 2.1
260      */

261     private int extraArrayDimensions = 0;
262
263     /**
264      * The list of thrown exception names (element type: <code>Name</code>).
265      * Defaults to an empty list.
266      */

267     private ASTNode.NodeList thrownExceptions =
268         new ASTNode.NodeList(THROWN_EXCEPTIONS_PROPERTY);
269
270     /**
271      * The method body, or <code>null</code> if none.
272      * Defaults to none.
273      */

274     private Block optionalBody = null;
275     
276     /**
277      * Creates a new AST node for a method declaration owned
278      * by the given AST. By default, the declaration is for a method of an
279      * unspecified, but legal, name; no modifiers; no javadoc; no type
280      * parameters; void return type; no parameters; no array dimensions after
281      * the parameters; no thrown exceptions; and no body (as opposed to an
282      * empty body).
283      * <p>
284      * N.B. This constructor is package-private; all subclasses must be
285      * declared in the same package; clients are unable to declare
286      * additional subclasses.
287      * </p>
288      *
289      * @param ast the AST that is to own this node
290      */

291     MethodDeclaration(AST ast) {
292         super(ast);
293         if (ast.apiLevel >= AST.JLS3) {
294             this.typeParameters = new ASTNode.NodeList(TYPE_PARAMETERS_PROPERTY);
295         }
296     }
297
298     /* (omit javadoc for this method)
299      * Method declared on ASTNode.
300      * @since 3.0
301      */

302     final List JavaDoc internalStructuralPropertiesForType(int apiLevel) {
303         return propertyDescriptors(apiLevel);
304     }
305     
306     /* (omit javadoc for this method)
307      * Method declared on ASTNode.
308      */

309     final int internalGetSetIntProperty(SimplePropertyDescriptor property, boolean get, int value) {
310         if (property == MODIFIERS_PROPERTY) {
311             if (get) {
312                 return getModifiers();
313             } else {
314                 internalSetModifiers(value);
315                 return 0;
316             }
317         }
318         if (property == EXTRA_DIMENSIONS_PROPERTY) {
319             if (get) {
320                 return getExtraDimensions();
321             } else {
322                 setExtraDimensions(value);
323                 return 0;
324             }
325         }
326         // allow default implementation to flag the error
327
return super.internalGetSetIntProperty(property, get, value);
328     }
329
330     /* (omit javadoc for this method)
331      * Method declared on ASTNode.
332      */

333     final boolean internalGetSetBooleanProperty(SimplePropertyDescriptor property, boolean get, boolean value) {
334         if (property == CONSTRUCTOR_PROPERTY) {
335             if (get) {
336                 return isConstructor();
337             } else {
338                 setConstructor(value);
339                 return false;
340             }
341         }
342         // allow default implementation to flag the error
343
return super.internalGetSetBooleanProperty(property, get, value);
344     }
345     
346     /* (omit javadoc for this method)
347      * Method declared on ASTNode.
348      */

349     final ASTNode internalGetSetChildProperty(ChildPropertyDescriptor property, boolean get, ASTNode child) {
350         if (property == JAVADOC_PROPERTY) {
351             if (get) {
352                 return getJavadoc();
353             } else {
354                 setJavadoc((Javadoc) child);
355                 return null;
356             }
357         }
358         if (property == NAME_PROPERTY) {
359             if (get) {
360                 return getName();
361             } else {
362                 setName((SimpleName) child);
363                 return null;
364             }
365         }
366         if (property == RETURN_TYPE_PROPERTY) {
367             if (get) {
368                 return getReturnType();
369             } else {
370                 setReturnType((Type) child);
371                 return null;
372             }
373         }
374         if (property == RETURN_TYPE2_PROPERTY) {
375             if (get) {
376                 return getReturnType2();
377             } else {
378                 setReturnType2((Type) child);
379                 return null;
380             }
381         }
382         if (property == BODY_PROPERTY) {
383             if (get) {
384                 return getBody();
385             } else {
386                 setBody((Block) child);
387                 return null;
388             }
389         }
390         // allow default implementation to flag the error
391
return super.internalGetSetChildProperty(property, get, child);
392     }
393     
394     /* (omit javadoc for this method)
395      * Method declared on ASTNode.
396      */

397     final List JavaDoc internalGetChildListProperty(ChildListPropertyDescriptor property) {
398         if (property == MODIFIERS2_PROPERTY) {
399             return modifiers();
400         }
401         if (property == TYPE_PARAMETERS_PROPERTY) {
402             return typeParameters();
403         }
404         if (property == PARAMETERS_PROPERTY) {
405             return parameters();
406         }
407         if (property == THROWN_EXCEPTIONS_PROPERTY) {
408             return thrownExceptions();
409         }
410         // allow default implementation to flag the error
411
return super.internalGetChildListProperty(property);
412     }
413     
414     /* (omit javadoc for this method)
415      * Method declared on BodyDeclaration.
416      */

417     final ChildPropertyDescriptor internalJavadocProperty() {
418         return JAVADOC_PROPERTY;
419     }
420
421     /* (omit javadoc for this method)
422      * Method declared on BodyDeclaration.
423      */

424     final ChildListPropertyDescriptor internalModifiers2Property() {
425         return MODIFIERS2_PROPERTY;
426     }
427
428     /* (omit javadoc for this method)
429      * Method declared on BodyDeclaration.
430      */

431     final SimplePropertyDescriptor internalModifiersProperty() {
432         return MODIFIERS_PROPERTY;
433     }
434
435     /* (omit javadoc for this method)
436      * Method declared on ASTNode.
437      */

438     final int getNodeType0() {
439         return METHOD_DECLARATION;
440     }
441
442     /* (omit javadoc for this method)
443      * Method declared on ASTNode.
444      */

445     ASTNode clone0(AST target) {
446         MethodDeclaration result = new MethodDeclaration(target);
447         result.setSourceRange(this.getStartPosition(), this.getLength());
448         result.setJavadoc(
449             (Javadoc) ASTNode.copySubtree(target, getJavadoc()));
450         if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
451             result.internalSetModifiers(getModifiers());
452             result.setReturnType(
453                     (Type) ASTNode.copySubtree(target, getReturnType()));
454         }
455         if (this.ast.apiLevel >= AST.JLS3) {
456             result.modifiers().addAll(ASTNode.copySubtrees(target, modifiers()));
457             result.typeParameters().addAll(
458                     ASTNode.copySubtrees(target, typeParameters()));
459             result.setReturnType2(
460                     (Type) ASTNode.copySubtree(target, getReturnType2()));
461         }
462         result.setConstructor(isConstructor());
463         result.setExtraDimensions(getExtraDimensions());
464         result.setName((SimpleName) getName().clone(target));
465         result.parameters().addAll(
466             ASTNode.copySubtrees(target, parameters()));
467         result.thrownExceptions().addAll(
468             ASTNode.copySubtrees(target, thrownExceptions()));
469         result.setBody(
470             (Block) ASTNode.copySubtree(target, getBody()));
471         return result;
472     }
473
474     /* (omit javadoc for this method)
475      * Method declared on ASTNode.
476      */

477     final boolean subtreeMatch0(ASTMatcher matcher, Object JavaDoc other) {
478         // dispatch to correct overloaded match method
479
return matcher.match(this, other);
480     }
481     
482     /* (omit javadoc for this method)
483      * Method declared on ASTNode.
484      */

485     void accept0(ASTVisitor visitor) {
486         boolean visitChildren = visitor.visit(this);
487         if (visitChildren) {
488             // visit children in normal left to right reading order
489
acceptChild(visitor, getJavadoc());
490             if (this.ast.apiLevel == AST.JLS2_INTERNAL) {
491                 acceptChild(visitor, getReturnType());
492             } else {
493                 acceptChildren(visitor, this.modifiers);
494                 acceptChildren(visitor, this.typeParameters);
495                 acceptChild(visitor, getReturnType2());
496             }
497             // n.b. visit return type even for constructors
498
acceptChild(visitor, getName());
499             acceptChildren(visitor, this.parameters);
500             acceptChildren(visitor, this.thrownExceptions);
501             acceptChild(visitor, getBody());
502         }
503         visitor.endVisit(this);
504     }
505     
506     /**
507      * Returns whether this declaration declares a constructor or a method.
508      *
509      * @return <code>true</code> if this is a constructor declaration,
510      * and <code>false</code> if this is a method declaration
511      */

512     public boolean isConstructor() {
513         return this.isConstructor;
514     }
515     
516     /**
517      * Sets whether this declaration declares a constructor or a method.
518      *
519      * @param isConstructor <code>true</code> for a constructor declaration,
520      * and <code>false</code> for a method declaration
521      */

522     public void setConstructor(boolean isConstructor) {
523         preValueChange(CONSTRUCTOR_PROPERTY);
524         this.isConstructor = isConstructor;
525         postValueChange(CONSTRUCTOR_PROPERTY);
526     }
527
528     /**
529      * Returns the live ordered list of type parameters of this method
530      * declaration (added in JLS3 API). This list is non-empty for parameterized methods.
531      *
532      * @return the live list of type parameters
533      * (element type: <code>TypeParameter</code>)
534      * @exception UnsupportedOperationException if this operation is used in
535      * a JLS2 AST
536      * @since 3.1
537      */

538     public List JavaDoc typeParameters() {
539         // more efficient than just calling unsupportedIn2() to check
540
if (this.typeParameters == null) {
541             unsupportedIn2();
542         }
543         return this.typeParameters;
544     }
545     
546     /**
547      * Returns the name of the method declared in this method declaration.
548      * For a constructor declaration, this should be the same as the name
549      * of the class.
550      *
551      * @return the method name node
552      */

553     public SimpleName getName() {
554         if (this.methodName == null) {
555             // lazy init must be thread-safe for readers
556
synchronized (this) {
557                 if (this.methodName == null) {
558                     preLazyInit();
559                     this.methodName = new SimpleName(this.ast);
560                     postLazyInit(this.methodName, NAME_PROPERTY);
561                 }
562             }
563         }
564         return this.methodName;
565     }
566     
567     /**
568      * Sets the name of the method declared in this method declaration to the
569      * given name. For a constructor declaration, this should be the same as
570      * the name of the class.
571      *
572      * @param methodName the new method name
573      * @exception IllegalArgumentException if:
574      * <ul>
575      * <li>the node belongs to a different AST</li>
576      * <li>the node already has a parent</li>
577      * </ul>
578      */

579     public void setName(SimpleName methodName) {
580         if (methodName == null) {
581             throw new IllegalArgumentException JavaDoc();
582         }
583         ASTNode oldChild = this.methodName;
584         preReplaceChild(oldChild, methodName, NAME_PROPERTY);
585         this.methodName = methodName;
586         postReplaceChild(oldChild, methodName, NAME_PROPERTY);
587     }
588
589     /**
590      * Returns the live ordered list of method parameter declarations for this
591      * method declaration.
592      *
593      * @return the live list of method parameter declarations
594      * (element type: <code>SingleVariableDeclaration</code>)
595      */

596     public List JavaDoc parameters() {
597         return this.parameters;
598     }
599     
600     /**
601      * Returns whether this method declaration declares a
602      * variable arity method (added in JLS3 API). The convenience method checks
603      * whether the last parameter is so marked.
604      *
605      * @return <code>true</code> if this is a variable arity method declaration,
606      * and <code>false</code> otherwise
607      * @exception UnsupportedOperationException if this operation is used in
608      * a JLS2 AST
609      * @see SingleVariableDeclaration#isVarargs()
610      * @since 3.1
611      */

612     public boolean isVarargs() {
613         // more efficient than just calling unsupportedIn2() to check
614
if (this.modifiers == null) {
615             unsupportedIn2();
616         }
617         if (parameters().isEmpty()) {
618             return false;
619         } else {
620             SingleVariableDeclaration v = (SingleVariableDeclaration) parameters().get(parameters().size() - 1);
621             return v.isVarargs();
622         }
623     }
624     
625     /**
626      * Returns the live ordered list of thrown exception names in this method
627      * declaration.
628      *
629      * @return the live list of exception names
630      * (element type: <code>Name</code>)
631      */

632     public List JavaDoc thrownExceptions() {
633         return this.thrownExceptions;
634     }
635     
636     /**
637      * Returns the return type of the method declared in this method
638      * declaration, exclusive of any extra array dimensions (JLS2 API only).
639      * This is one of the few places where the void type is meaningful.
640      * <p>
641      * Note that this child is not relevant for constructor declarations
642      * (although, it does still figure in subtree equality comparisons
643      * and visits), and is devoid of the binding information ordinarily
644      * available.
645      * </p>
646      *
647      * @return the return type, possibly the void primitive type
648      * @exception UnsupportedOperationException if this operation is used in
649      * an AST later than JLS2
650      * @deprecated In the JLS3 API, this method is replaced by {@link #getReturnType2()},
651      * which may return <code>null</code>.
652      */

653     public Type getReturnType() {
654         return internalGetReturnType();
655     }
656     
657     /**
658      * Internal synonym for deprecated method. Used to avoid
659      * deprecation warnings.
660      * @since 3.1
661      */

662     /*package*/ final Type internalGetReturnType() {
663         supportedOnlyIn2();
664         if (this.returnType == null) {
665             // lazy init must be thread-safe for readers
666
synchronized (this) {
667                 if (this.returnType == null) {
668                     preLazyInit();
669                     this.returnType = this.ast.newPrimitiveType(PrimitiveType.VOID);
670                     postLazyInit(this.returnType, RETURN_TYPE_PROPERTY);
671                 }
672             }
673         }
674         return this.returnType;
675     }
676
677     /**
678      * Sets the return type of the method declared in this method declaration
679      * to the given type, exclusive of any extra array dimensions (JLS2 API only). This is one
680      * of the few places where the void type is meaningful.
681      * <p>
682      * Note that this child is not relevant for constructor declarations
683      * (although it does still figure in subtree equality comparisons and visits).
684      * </p>
685      *
686      * @param type the new return type, possibly the void primitive type
687      * @exception IllegalArgumentException if:
688      * <ul>
689      * <li>the node belongs to a different AST</li>
690      * <li>the node already has a parent</li>
691      * </ul>
692      * @exception UnsupportedOperationException if this operation is used in
693      * an AST later than JLS2
694      * @deprecated In the JLS3 API, this method is replaced by
695      * {@link #setReturnType2(Type)}, which accepts <code>null</code>.
696      */

697     public void setReturnType(Type type) {
698         internalSetReturnType(type);
699     }
700     
701     /**
702      * Internal synonym for deprecated method. Used to avoid
703      * deprecation warnings.
704      * @since 3.1
705      */

706     /*package*/ void internalSetReturnType(Type type) {
707         supportedOnlyIn2();
708         if (type == null) {
709             throw new IllegalArgumentException JavaDoc();
710         }
711         ASTNode oldChild = this.returnType;
712         preReplaceChild(oldChild, type, RETURN_TYPE_PROPERTY);
713         this.returnType = type;
714         postReplaceChild(oldChild, type, RETURN_TYPE_PROPERTY);
715     }
716
717     /**
718      * Returns the return type of the method declared in this method
719      * declaration, exclusive of any extra array dimensions (added in JLS3 API).
720      * This is one of the few places where the void type is meaningful.
721      * <p>
722      * Note that this child is not relevant for constructor declarations
723      * (although, if present, it does still figure in subtree equality comparisons
724      * and visits), and is devoid of the binding information ordinarily
725      * available. In the JLS2 API, the return type is mandatory.
726      * In the JLS3 API, the return type is optional.
727      * </p>
728      *
729      * @return the return type, possibly the void primitive type,
730      * or <code>null</code> if none
731      * @exception UnsupportedOperationException if this operation is used in
732      * a JLS2 AST
733      * @since 3.1
734      */

735     public Type getReturnType2() {
736         unsupportedIn2();
737         if (this.returnType == null && !this.returnType2Initialized) {
738             // lazy init must be thread-safe for readers
739
synchronized (this) {
740                 if (this.returnType == null && !this.returnType2Initialized) {
741                     preLazyInit();
742                     this.returnType = this.ast.newPrimitiveType(PrimitiveType.VOID);
743                     this.returnType2Initialized = true;
744                     postLazyInit(this.returnType, RETURN_TYPE2_PROPERTY);
745                 }
746             }
747         }
748         return this.returnType;
749     }
750
751     /**
752      * Sets the return type of the method declared in this method declaration
753      * to the given type, exclusive of any extra array dimensions (added in JLS3 API).
754      * This is one of the few places where the void type is meaningful.
755      * <p>
756      * Note that this child is not relevant for constructor declarations
757      * (although it does still figure in subtree equality comparisons and visits).
758      * In the JLS2 API, the return type is mandatory.
759      * In the JLS3 API, the return type is optional.
760      * </p>
761      *
762      * @param type the new return type, possibly the void primitive type,
763      * or <code>null</code> if none
764      * @exception UnsupportedOperationException if this operation is used in
765      * a JLS2 AST
766      * @exception IllegalArgumentException if:
767      * <ul>
768      * <li>the node belongs to a different AST</li>
769      * <li>the node already has a parent</li>
770      * </ul>
771      * @since 3.1
772      */

773     public void setReturnType2(Type type) {
774         unsupportedIn2();
775         this.returnType2Initialized = true;
776         ASTNode oldChild = this.returnType;
777         preReplaceChild(oldChild, type, RETURN_TYPE2_PROPERTY);
778         this.returnType = type;
779         postReplaceChild(oldChild, type, RETURN_TYPE2_PROPERTY);
780     }
781
782     /**
783      * Returns the number of extra array dimensions over and above the
784      * explicitly-specified return type.
785      * <p>
786      * For example, <code>int foo()[][]</code> has a return type of
787      * <code>int</code> and two extra array dimensions;
788      * <code>int[][] foo()</code> has a return type of <code>int[][]</code>
789      * and zero extra array dimensions. The two constructs have different
790      * ASTs, even though there are really syntactic variants of the same
791      * method declaration.
792      * </p>
793      *
794      * @return the number of extra array dimensions
795      * @since 2.1
796      */

797     public int getExtraDimensions() {
798         return this.extraArrayDimensions;
799     }
800
801     /**
802      * Sets the number of extra array dimensions over and above the
803      * explicitly-specified return type.
804      * <p>
805      * For example, <code>int foo()[][]</code> is rendered as a return
806      * type of <code>int</code> with two extra array dimensions;
807      * <code>int[][] foo()</code> is rendered as a return type of
808      * <code>int[][]</code> with zero extra array dimensions. The two
809      * constructs have different ASTs, even though there are really syntactic
810      * variants of the same method declaration.
811      * </p>
812      *
813      * @param dimensions the number of array dimensions
814      * @exception IllegalArgumentException if the number of dimensions is
815      * negative
816      * @since 2.1
817      */

818     public void setExtraDimensions(int dimensions) {
819         if (dimensions < 0) {
820             throw new IllegalArgumentException JavaDoc();
821         }
822         preValueChange(EXTRA_DIMENSIONS_PROPERTY);
823         this.extraArrayDimensions = dimensions;
824         postValueChange(EXTRA_DIMENSIONS_PROPERTY);
825     }
826
827     /**
828      * Returns the body of this method declaration, or <code>null</code> if
829      * this method has <b>no</b> body.
830      * <p>
831      * Note that there is a subtle difference between having no body and having
832      * an empty body ("{}").
833      * </p>
834      *
835      * @return the method body, or <code>null</code> if this method has no
836      * body
837      */

838     public Block getBody() {
839         return this.optionalBody;
840     }
841
842     /**
843      * Sets or clears the body of this method declaration.
844      * <p>
845      * Note that there is a subtle difference between having no body
846      * (as in <code>"void foo();"</code>) and having an empty body (as in
847      * "void foo() {}"). Abstract methods, and methods declared in interfaces,
848      * have no body. Non-abstract methods, and all constructors, have a body.
849      * </p>
850      *
851      * @param body the block node, or <code>null</code> if
852      * there is none
853      * @exception IllegalArgumentException if:
854      * <ul>
855      * <li>the node belongs to a different AST</li>
856      * <li>the node already has a parent</li>
857      * <li>a cycle in would be created</li>
858      * </ul>
859      */

860     public void setBody(Block body) {
861         // a MethodDeclaration may occur in a Block - must check cycles
862
ASTNode oldChild = this.optionalBody;
863         preReplaceChild(oldChild, body, BODY_PROPERTY);
864         this.optionalBody = body;
865         postReplaceChild(oldChild, body, BODY_PROPERTY);
866     }
867
868     /**
869      * Resolves and returns the binding for the method or constructor declared
870      * in this method or constructor declaration.
871      * <p>
872      * Note that bindings are generally unavailable unless requested when the
873      * AST is being built.
874      * </p>
875      *
876      * @return the binding, or <code>null</code> if the binding cannot be
877      * resolved
878      */

879     public IMethodBinding resolveBinding() {
880         return this.ast.getBindingResolver().resolveMethod(this);
881     }
882
883     /* (omit javadoc for this method)
884      * Method declared on ASTNode.
885      */

886     int memSize() {
887         return super.memSize() + 9 * 4;
888     }
889     
890     /* (omit javadoc for this method)
891      * Method declared on ASTNode.
892      */

893     int treeSize() {
894         return
895             memSize()
896             + (this.optionalDocComment == null ? 0 : getJavadoc().treeSize())
897             + (this.modifiers == null ? 0 : this.modifiers.listSize())
898             + (this.typeParameters == null ? 0 : this.typeParameters.listSize())
899             + (this.methodName == null ? 0 : getName().treeSize())
900             + (this.returnType == null ? 0 : this.returnType.treeSize())
901             + this.parameters.listSize()
902             + this.thrownExceptions.listSize()
903             + (this.optionalBody == null ? 0 : getBody().treeSize());
904     }
905 }
906
907
Popular Tags