A massive organize imports and formatting of the sources using default Eclipse code...
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / jdom / DOMMethod.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2003 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials 
4  * are made available under the terms of the Common Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/cpl-v10.html
7  * 
8  * Contributors:
9  *     IBM Corporation - initial API and implementation
10  *******************************************************************************/
11 package net.sourceforge.phpdt.internal.core.jdom;
12
13 import net.sourceforge.phpdt.core.IJavaElement;
14 import net.sourceforge.phpdt.core.IType;
15 import net.sourceforge.phpdt.core.Signature;
16 import net.sourceforge.phpdt.core.jdom.IDOMMethod;
17 import net.sourceforge.phpdt.core.jdom.IDOMNode;
18 import net.sourceforge.phpdt.internal.compiler.util.Util;
19 import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer;
20 import net.sourceforge.phpdt.internal.core.util.CharArrayOps;
21
22 /**
23  * DOMMethod provides an implementation of IDOMMethod.
24  * 
25  * @see IDOMMethod
26  * @see DOMNode
27  */
28
29 class DOMMethod extends DOMMember implements IDOMMethod {
30
31         /**
32          * Contains the return type of the method when the return type has been
33          * altered from the contents in the document, otherwise <code>null</code>.
34          */
35         protected String fReturnType;
36
37         /**
38          * The original inclusive source range of the method's return type in the
39          * document, or -1's if no return type is present in the document. If the
40          * return type of this method is qualified with '[]' following the parameter
41          * list, this array has four entries. In this case, the last two entries of
42          * the array are the inclusive source range of the array qualifiers.
43          */
44         protected int[] fReturnTypeRange;
45
46         /**
47          * Contains the textual representation of the method's parameter list,
48          * including open and closing parentheses when the parameters had been
49          * altered from the contents in the document, otherwise <code>null</code>.
50          */
51         protected char[] fParameterList;
52
53         /**
54          * The original inclusive source range of the method's parameter list in the
55          * document.
56          */
57         protected int[] fParameterRange;
58
59         /**
60          * Contains the textual representation of the method's exception list when
61          * the exceptions had been altered from the contents in the document,
62          * otherwise <code>null</code>. The exception list is a comment delimited
63          * list of exceptions, not including the "throws" keyword.
64          */
65         protected char[] fExceptionList;
66
67         /**
68          * The original inclusive source range of the method's exception list in the
69          * document.
70          */
71         protected int[] fExceptionRange;
72
73         /**
74          * Contains the method's body when the body has been altered from the
75          * contents in the document, otherwise <code>null</code>. The body
76          * includes everything between and including the enclosing braces, and
77          * trailing whitespace.
78          */
79         protected String fBody;
80
81         /**
82          * The original inclusive source range of the method's body.
83          */
84         protected int[] fBodyRange;
85
86         /**
87          * Names of parameters in the method parameter list, or <code>null</code>
88          * if the method has no parameters.
89          */
90         protected String[] fParameterNames;
91
92         /**
93          * Types of parameters in the method parameter list, or <code>null</code>
94          * if the method has no parameters.
95          */
96         protected String[] fParameterTypes;
97
98         /**
99          * The exceptions the method throws, or <code>null</code> if the method
100          * throws no exceptions.
101          */
102         protected String[] fExceptions;
103
104         /**
105          * Constructs an empty method node.
106          */
107         DOMMethod() {
108
109         }
110
111         /**
112          * Creates a new detailed METHOD document fragment on the given range of the
113          * document.
114          * 
115          * @param document -
116          *            the document containing this node's original contents
117          * @param sourceRange -
118          *            a two element array of integers describing the entire
119          *            inclusive source range of this node within its document.
120          *            Contents start on and include the character at the first
121          *            position. Contents end on and include the character at the
122          *            last position. An array of -1's indicates this node's contents
123          *            do not exist in the document.
124          * @param name -
125          *            the identifier portion of the name of this node, or
126          *            <code>null</code> if this node does not have a name
127          * @param nameRange -
128          *            a two element array of integers describing the entire
129          *            inclusive source range of this node's name within its
130          *            document, including any array qualifiers that might
131          *            immediately follow the name or -1's if this node does not have
132          *            a name.
133          * @param commentRange -
134          *            a two element array describing the comments that precede the
135          *            member declaration. The first matches the start of this node's
136          *            sourceRange, and the second is the new-line or first
137          *            non-whitespace character following the last comment. If no
138          *            comments are present, this array contains two -1's.
139          * @param flags -
140          *            an integer representing the modifiers for this member. The
141          *            integer can be analyzed with net.sourceforge.phpdt.core.Flags
142          * @param modifierRange -
143          *            a two element array describing the location of modifiers for
144          *            this member within its source range. The first integer is the
145          *            first character of the first modifier for this member, and the
146          *            second integer is the last whitespace character preceeding the
147          *            next part of this member declaration. If there are no
148          *            modifiers present in this node's source code (that is, package
149          *            default visibility), this array contains two -1's.
150          * @param isConstructor -
151          *            true if the method is a contructor, otherwise false
152          * @param returnType -
153          *            the normalized return type of this method
154          * @param returnTypeRange -
155          *            a two element array describing the location of the return type
156          *            within the method's source range. The first integer is is the
157          *            position of the first character in the return type, and the
158          *            second integer is the position of the last character in the
159          *            return type. For constructors, the contents of this array are
160          *            -1's. If the return type of this method is qualified with '[]'
161          *            following the parameter list, this array has four entries. In
162          *            this case, the last two entries of the array are the inclusive
163          *            source range of the array qualifiers.
164          * @param parameterTypes -
165          *            an array of parameter types in the method declaration or
166          *            <code>null</code> if the method has no parameters
167          * @param parameterNames -
168          *            an array of parameter names in the method declaration or
169          *            <code>null</code> if the method has no parameters
170          * @param parameterRange -
171          *            a two element array describing the location of the parameter
172          *            list in the method. The first integer is the location of the
173          *            open parenthesis and the second integer is the location of the
174          *            closing parenthesis.
175          * @param exceptions -
176          *            an array of the names of exceptions thrown by this method or
177          *            <code>null</code> if the method throws no exceptions
178          * @param exceptionRange -
179          *            a two element array describing the location of the exception
180          *            list in the method declaration. The first integer is the
181          *            position of the first character in the first exception the
182          *            method throws, and the second integer is the position of the
183          *            last character of the last exception this method throws.
184          * @param bodyRange -
185          *            a two element array describing the location of the method's
186          *            body. The first integer is the first character following the
187          *            method's parameter list, or exception list (if present). The
188          *            second integer is the location of the last character in the
189          *            method's source range.
190          */
191         DOMMethod(char[] document, int[] sourceRange, String name, int[] nameRange,
192                         int[] commentRange, int flags, int[] modifierRange,
193                         boolean isConstructor, String returnType, int[] returnTypeRange,
194                         String[] parameterTypes, String[] parameterNames,
195                         int[] parameterRange, String[] exceptions, int[] exceptionRange,
196                         int[] bodyRange) {
197                 super(document, sourceRange, name, nameRange, commentRange, flags,
198                                 modifierRange);
199
200                 setMask(MASK_IS_CONSTRUCTOR, isConstructor);
201                 fReturnType = returnType;
202                 fReturnTypeRange = returnTypeRange;
203                 fParameterTypes = parameterTypes;
204                 fParameterNames = parameterNames;
205                 fParameterRange = parameterRange;
206                 fExceptionRange = exceptionRange;
207                 fExceptions = exceptions;
208                 setHasBody(true);
209                 fBodyRange = bodyRange;
210                 setMask(MASK_DETAILED_SOURCE_INDEXES, true);
211
212         }
213
214         /**
215          * Creates a new simple METHOD document fragment on the given range of the
216          * document.
217          * 
218          * @param document -
219          *            the document containing this node's original contents
220          * @param sourceRange -
221          *            a two element array of integers describing the entire
222          *            inclusive source range of this node within its document.
223          *            Contents start on and include the character at the first
224          *            position. Contents end on and include the character at the
225          *            last position. An array of -1's indicates this node's contents
226          *            do not exist in the document.
227          * @param name -
228          *            the identifier portion of the name of this node, or
229          *            <code>null</code> if this node does not have a name
230          * @param nameRange -
231          *            a two element array of integers describing the entire
232          *            inclusive source range of this node's name within its
233          *            document, including any array qualifiers that might
234          *            immediately follow the name or -1's if this node does not have
235          *            a name.
236          * @param flags -
237          *            an integer representing the modifiers for this member. The
238          *            integer can be analyzed with net.sourceforge.phpdt.core.Flags
239          * @param isConstructor -
240          *            true if the method is a contructor, otherwise false
241          * @param returnType -
242          *            the normalized return type of this method
243          * @param parameterTypes -
244          *            an array of parameter types in the method declaration or
245          *            <code>null</code> if the method has no parameters
246          * @param parameterNames -
247          *            an array of parameter names in the method declaration or
248          *            <code>null</code> if the method has no parameters
249          * @param exceptions -
250          *            an array of the names of exceptions thrown by this method or
251          *            <code>null</code> if the method throws no exceptions
252          */
253         DOMMethod(char[] document, int[] sourceRange, String name, int[] nameRange,
254                         int flags, boolean isConstructor, String returnType,
255                         String[] parameterTypes, String[] parameterNames,
256                         String[] exceptions) {
257                 this(document, sourceRange, name, nameRange, new int[] { -1, -1 },
258                                 flags, new int[] { -1, -1 }, isConstructor, returnType,
259                                 new int[] { -1, -1 }, parameterTypes, parameterNames,
260                                 new int[] { -1, -1 }, exceptions, new int[] { -1, -1 },
261                                 new int[] { -1, -1 });
262                 setMask(MASK_DETAILED_SOURCE_INDEXES, false);
263         }
264
265         /**
266          * @see IDOMMethod#addException(String)
267          */
268         public void addException(String name) throws IllegalArgumentException {
269                 if (name == null) {
270                         throw new IllegalArgumentException(Util
271                                         .bind("dom.nullExceptionType")); //$NON-NLS-1$
272                 }
273                 if (fExceptions == null) {
274                         fExceptions = new String[1];
275                         fExceptions[0] = name;
276                 } else {
277                         fExceptions = appendString(fExceptions, name);
278                 }
279                 setExceptions(fExceptions);
280         }
281
282         /**
283          * @see IDOMMethod#addParameter(String, String)
284          */
285         public void addParameter(String type, String name)
286                         throws IllegalArgumentException {
287                 if (type == null) {
288                         throw new IllegalArgumentException(Util
289                                         .bind("dom.nullTypeParameter")); //$NON-NLS-1$
290                 }
291                 if (name == null) {
292                         throw new IllegalArgumentException(Util
293                                         .bind("dom.nullNameParameter")); //$NON-NLS-1$
294                 }
295                 if (fParameterNames == null) {
296                         fParameterNames = new String[1];
297                         fParameterNames[0] = name;
298                 } else {
299                         fParameterNames = appendString(fParameterNames, name);
300                 }
301                 if (fParameterTypes == null) {
302                         fParameterTypes = new String[1];
303                         fParameterTypes[0] = type;
304                 } else {
305                         fParameterTypes = appendString(fParameterTypes, type);
306                 }
307                 setParameters(fParameterTypes, fParameterNames);
308         }
309
310         /**
311          * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
312          */
313         protected void appendMemberBodyContents(CharArrayBuffer buffer) {
314                 if (fBody != null) {
315                         buffer.append(fBody);
316                 } else {
317                         buffer.append(fDocument, fBodyRange[0], fBodyRange[1] + 1
318                                         - fBodyRange[0]);
319                 }
320         }
321
322         /**
323          * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer)
324          */
325         protected void appendMemberDeclarationContents(CharArrayBuffer buffer) {
326
327                 if (isConstructor()) {
328                         buffer.append(getConstructorName()).append(fDocument,
329                                         fNameRange[1] + 1, fParameterRange[0] - fNameRange[1] - 1);
330                 } else {
331                         buffer.append(getReturnTypeContents());
332                         if (fReturnTypeRange[0] >= 0) {
333                                 buffer.append(fDocument, fReturnTypeRange[1] + 1, fNameRange[0]
334                                                 - fReturnTypeRange[1] - 1);
335                         } else {
336                                 buffer.append(' ');
337                         }
338                         buffer.append(getNameContents()).append(fDocument,
339                                         fNameRange[1] + 1, fParameterRange[0] - fNameRange[1] - 1);
340                 }
341                 if (fParameterList != null) {
342                         buffer.append(fParameterList);
343                 } else {
344                         buffer.append(fDocument, fParameterRange[0], fParameterRange[1] + 1
345                                         - fParameterRange[0]);
346                 }
347                 int start;
348                 if (hasTrailingArrayQualifier() && isReturnTypeAltered()) {
349                         start = fReturnTypeRange[3] + 1;
350                 } else {
351                         start = fParameterRange[1] + 1;
352                 }
353                 if (fExceptions != null) {
354                         // add 'throws' keyword
355                         if (fExceptionRange[0] >= 0) {
356                                 buffer.append(fDocument, start, fExceptionRange[0] - start);
357                         } else {
358                                 buffer.append(" throws "); //$NON-NLS-1$
359                         }
360                         // add exception list
361                         if (fExceptionList != null) {
362                                 buffer.append(fExceptionList);
363                                 // add space before body
364                                 if (fExceptionRange[0] >= 0) {
365                                         buffer.append(fDocument, fExceptionRange[1] + 1,
366                                                         fBodyRange[0] - fExceptionRange[1] - 1);
367                                 } else {
368                                         buffer.append(fDocument, fParameterRange[1] + 1,
369                                                         fBodyRange[0] - fParameterRange[1] - 1);
370                                 }
371                         } else {
372                                 // add list and space before body
373                                 buffer.append(fDocument, fExceptionRange[0], fBodyRange[0]
374                                                 - fExceptionRange[0]);
375                         }
376                 } else {
377                         // add space before body
378                         if (fExceptionRange[0] >= 0) {
379                                 buffer.append(fDocument, fExceptionRange[1] + 1, fBodyRange[0]
380                                                 - fExceptionRange[1] - 1);
381                         } else {
382                                 buffer.append(fDocument, start, fBodyRange[0] - start);
383                         }
384                 }
385
386         }
387
388         /**
389          * @see DOMNode#appendSimpleContents(CharArrayBuffer)
390          */
391         protected void appendSimpleContents(CharArrayBuffer buffer) {
392                 // append eveything before my name
393                 buffer.append(fDocument, fSourceRange[0], fNameRange[0]
394                                 - fSourceRange[0]);
395                 // append my name
396                 if (isConstructor()) {
397                         buffer.append(getConstructorName());
398                 } else {
399                         buffer.append(fName);
400                 }
401                 // append everything after my name
402                 buffer.append(fDocument, fNameRange[1] + 1, fSourceRange[1]
403                                 - fNameRange[1]);
404         }
405
406         /**
407          * @see IDOMMethod#getBody()
408          */
409         public String getBody() {
410                 becomeDetailed();
411                 if (hasBody()) {
412                         if (fBody != null) {
413                                 return fBody;
414                         } else {
415                                 return CharArrayOps.substring(fDocument, fBodyRange[0],
416                                                 fBodyRange[1] + 1 - fBodyRange[0]);
417                         }
418                 } else {
419                         return null;
420                 }
421         }
422
423         /**
424          * Returns the simple name of the enclsoing type for this constructor. If
425          * the constuctor is not currently enclosed in a type, the original name of
426          * the constructor as found in the documnent is returned.
427          */
428         protected String getConstructorName() {
429
430                 if (isConstructor()) {
431                         if (getParent() != null) {
432                                 return getParent().getName();
433                         } else {
434                                 // If there is no parent use the original name
435                                 return new String(getNameContents());
436                         }
437                 } else {
438                         return null;
439                 }
440
441         }
442
443         /**
444          * @see DOMNode#getDetailedNode()
445          */
446         // protected DOMNode getDetailedNode() {
447         // return (DOMNode)getFactory().createMethod(getContents());
448         // }
449         /**
450          * @see IDOMMethod#getExceptions()
451          */
452         public String[] getExceptions() {
453                 return fExceptions;
454         }
455
456         /**
457          * @see IDOMNode#getJavaElement
458          */
459         public IJavaElement getJavaElement(IJavaElement parent)
460                         throws IllegalArgumentException {
461                 if (parent.getElementType() == IJavaElement.TYPE) {
462                         // translate parameter types to signatures
463                         String[] sigs = null;
464                         if (fParameterTypes != null) {
465                                 sigs = new String[fParameterTypes.length];
466                                 int i;
467                                 for (i = 0; i < fParameterTypes.length; i++) {
468                                         sigs[i] = Signature.createTypeSignature(fParameterTypes[i]
469                                                         .toCharArray(), false);
470                                 }
471                         }
472                         String name = null;
473                         if (isConstructor()) {
474                                 name = getConstructorName();
475                         } else {
476                                 name = getName();
477                         }
478                         return ((IType) parent).getMethod(name, sigs);
479                 } else {
480                         throw new IllegalArgumentException(Util
481                                         .bind("element.illegalParent")); //$NON-NLS-1$
482                 }
483         }
484
485         /**
486          * @see DOMMember#getMemberDeclarationStartPosition()
487          */
488         protected int getMemberDeclarationStartPosition() {
489                 if (fReturnTypeRange[0] >= 0) {
490                         return fReturnTypeRange[0];
491                 } else {
492                         return fNameRange[0];
493                 }
494         }
495
496         /**
497          * @see IDOMNode#getName()
498          */
499         public String getName() {
500                 if (isConstructor()) {
501                         return null;
502                 } else {
503                         return super.getName();
504                 }
505         }
506
507         /**
508          * @see IDOMNode#getNodeType()
509          */
510         public int getNodeType() {
511                 return IDOMNode.METHOD;
512         }
513
514         /**
515          * @see IDOMMethod#getParameterNames()
516          */
517         public String[] getParameterNames() {
518                 return fParameterNames;
519         }
520
521         /**
522          * @see IDOMMethod#getParameterTypes()
523          */
524         public String[] getParameterTypes() {
525                 return fParameterTypes;
526         }
527
528         /**
529          * @see IDOMMethod#getReturnType()
530          */
531         public String getReturnType() {
532                 if (isConstructor()) {
533                         return null;
534                 } else {
535                         return fReturnType;
536                 }
537         }
538
539         /**
540          * Returns the source code to be used for this method's return type
541          */
542         protected char[] getReturnTypeContents() {
543                 if (isConstructor()) {
544                         return null;
545                 } else {
546                         if (isReturnTypeAltered()) {
547                                 return fReturnType.toCharArray();
548                         } else {
549                                 return CharArrayOps.subarray(fDocument, fReturnTypeRange[0],
550                                                 fReturnTypeRange[1] + 1 - fReturnTypeRange[0]);
551                         }
552
553                 }
554         }
555
556         /**
557          * Returns true if this method's return type has array qualifiers ('[]')
558          * following the parameter list.
559          */
560         protected boolean hasTrailingArrayQualifier() {
561                 return fReturnTypeRange.length > 2;
562         }
563
564         /**
565          * @see IDOMMethod#isConstructor()
566          */
567         public boolean isConstructor() {
568                 return getMask(MASK_IS_CONSTRUCTOR);
569         }
570
571         /**
572          * Returns true if this method's return type has been altered from the
573          * original document contents.
574          */
575         protected boolean isReturnTypeAltered() {
576                 return getMask(MASK_RETURN_TYPE_ALTERED);
577         }
578
579         /**
580          * @see IDOMNode#isSigantureEqual(IDOMNode).
581          * 
582          * <p>
583          * Two methods have equal signatures if there names are the same and their
584          * parameter types are the same.
585          */
586         public boolean isSignatureEqual(IDOMNode node) {
587                 boolean ok = node.getNodeType() == getNodeType();
588                 if (ok) {
589                         IDOMMethod method = (IDOMMethod) node;
590                         ok = (isConstructor() && method.isConstructor())
591                                         || (!isConstructor() && !method.isConstructor());
592                         if (ok && !isConstructor()) {
593                                 ok = getName().equals(method.getName());
594                         }
595                         if (!ok) {
596                                 return false;
597                         }
598
599                         String[] types = method.getParameterTypes();
600                         if (fParameterTypes == null || fParameterTypes.length == 0) {
601                                 // this method has no parameters
602                                 if (types == null || types.length == 0) {
603                                         // the other method has no parameters either
604                                         return true;
605                                 }
606                         } else {
607                                 // this method has parameters
608                                 if (types == null || types.length == 0) {
609                                         // the other method has no parameters
610                                         return false;
611                                 }
612                                 if (fParameterTypes.length != types.length) {
613                                         // the methods have a different number of parameters
614                                         return false;
615                                 }
616                                 int i;
617                                 for (i = 0; i < types.length; i++) {
618                                         if (!fParameterTypes[i].equals(types[i])) {
619                                                 return false;
620                                         }
621                                 }
622                                 return true;
623                         }
624                 }
625                 return false;
626
627         }
628
629         /**
630          * @see DOMNode
631          */
632         protected DOMNode newDOMNode() {
633                 return new DOMMethod();
634         }
635
636         /**
637          * Offsets all the source indexes in this node by the given amount.
638          */
639         protected void offset(int offset) {
640                 super.offset(offset);
641                 offsetRange(fBodyRange, offset);
642                 offsetRange(fExceptionRange, offset);
643                 offsetRange(fParameterRange, offset);
644                 offsetRange(fReturnTypeRange, offset);
645         }
646
647         /**
648          * @see IDOMMethod#setBody
649          */
650         public void setBody(String body) {
651                 becomeDetailed();
652                 fragment();
653                 fBody = body;
654                 setHasBody(body != null);
655                 if (!hasBody()) {
656                         fBody = ";" + Util.LINE_SEPARATOR; //$NON-NLS-1$
657                 }
658         }
659
660         /**
661          * Sets the end of the body range
662          */
663         void setBodyRangeEnd(int end) {
664                 fBodyRange[1] = end;
665         }
666
667         /**
668          * @see IDOMMethod#setConstructor(boolean)
669          */
670         public void setConstructor(boolean b) {
671                 becomeDetailed();
672                 setMask(MASK_IS_CONSTRUCTOR, b);
673                 fragment();
674         }
675
676         /**
677          * @see IDOMMethod#setExceptions(char[][])
678          */
679         public void setExceptions(String[] names) {
680                 becomeDetailed();
681                 if (names == null || names.length == 0) {
682                         fExceptions = null;
683                 } else {
684                         fExceptions = names;
685                         CharArrayBuffer buffer = new CharArrayBuffer();
686                         char[] comma = new char[] { ',', ' ' };
687                         for (int i = 0, length = names.length; i < length; i++) {
688                                 if (i > 0)
689                                         buffer.append(comma);
690                                 buffer.append(names[i]);
691                         }
692                         fExceptionList = buffer.getContents();
693                 }
694                 fragment();
695         }
696
697         /**
698          * @see IDOMMethod#setName
699          */
700         public void setName(String name) {
701                 if (name == null) {
702                         throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
703                 } else {
704                         super.setName(name);
705                 }
706         }
707
708         /**
709          * @see IDOMMethod#setParameters(char[][], char[][])
710          */
711         public void setParameters(String[] types, String[] names)
712                         throws IllegalArgumentException {
713                 becomeDetailed();
714                 if (types == null || names == null) {
715                         if (types == null && names == null) {
716                                 fParameterTypes = null;
717                                 fParameterNames = null;
718                                 fParameterList = new char[] { '(', ')' };
719                         } else {
720                                 throw new IllegalArgumentException(Util
721                                                 .bind("dom.mismatchArgNamesAndTypes")); //$NON-NLS-1$
722                         }
723                 } else if (names.length != types.length) {
724                         throw new IllegalArgumentException(Util
725                                         .bind("dom.mismatchArgNamesAndTypes")); //$NON-NLS-1$
726                 } else if (names.length == 0) {
727                         setParameters(null, null);
728                 } else {
729                         fParameterNames = names;
730                         fParameterTypes = types;
731                         CharArrayBuffer parametersBuffer = new CharArrayBuffer();
732                         parametersBuffer.append("("); //$NON-NLS-1$
733                         char[] comma = new char[] { ',', ' ' };
734                         for (int i = 0; i < names.length; i++) {
735                                 if (i > 0) {
736                                         parametersBuffer.append(comma);
737                                 }
738                                 parametersBuffer.append(types[i]).append(' ').append(names[i]);
739                         }
740                         parametersBuffer.append(')');
741                         fParameterList = parametersBuffer.getContents();
742                 }
743                 fragment();
744         }
745
746         /**
747          * @see IDOMMethod#setReturnType(char[])
748          */
749         public void setReturnType(String name) throws IllegalArgumentException {
750                 if (name == null) {
751                         throw new IllegalArgumentException(Util.bind("dom.nullReturnType")); //$NON-NLS-1$
752                 }
753                 becomeDetailed();
754                 fragment();
755                 setReturnTypeAltered(true);
756                 fReturnType = name;
757         }
758
759         /**
760          * Sets the state of this method declaration as having the return type
761          * altered from the original document.
762          */
763         protected void setReturnTypeAltered(boolean typeAltered) {
764                 setMask(MASK_RETURN_TYPE_ALTERED, typeAltered);
765         }
766
767         /**
768          */
769         protected void setSourceRangeEnd(int end) {
770                 super.setSourceRangeEnd(end);
771                 fBodyRange[1] = end;
772         }
773
774         /**
775          * @see DOMNode#shareContents(DOMNode)
776          */
777         protected void shareContents(DOMNode node) {
778                 super.shareContents(node);
779                 DOMMethod method = (DOMMethod) node;
780                 fBody = method.fBody;
781                 fBodyRange = rangeCopy(method.fBodyRange);
782                 fExceptionList = method.fExceptionList;
783                 fExceptionRange = rangeCopy(method.fExceptionRange);
784                 fExceptions = method.fExceptions;
785                 fParameterList = method.fParameterList;
786                 fParameterNames = method.fParameterNames;
787                 fParameterRange = rangeCopy(method.fParameterRange);
788                 fParameterTypes = method.fParameterTypes;
789                 fReturnType = method.fReturnType;
790                 fReturnTypeRange = rangeCopy(method.fReturnTypeRange);
791         }
792
793         /**
794          * @see IDOMNode#toString()
795          */
796         public String toString() {
797                 if (isConstructor()) {
798                         return "CONSTRUCTOR"; //$NON-NLS-1$
799                 } else {
800                         return "METHOD: " + getName(); //$NON-NLS-1$
801                 }
802         }
803 }