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 / DOMBuilder.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 java.util.ArrayList;
14 import java.util.Map;
15
16 import net.sourceforge.phpdt.core.JavaCore;
17 import net.sourceforge.phpdt.core.compiler.IProblem;
18 import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit;
19 import net.sourceforge.phpdt.core.jdom.IDOMFactory;
20 import net.sourceforge.phpdt.core.jdom.IDOMNode;
21 import net.sourceforge.phpdt.core.jdom.IDOMPackage;
22 import net.sourceforge.phpdt.internal.compiler.DocumentElementParser;
23 import net.sourceforge.phpdt.internal.compiler.IDocumentElementRequestor;
24 import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
25 import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
26 import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
27 import net.sourceforge.phpdt.internal.core.util.CharArrayOps;
28
29 /**
30  * The DOMBuilder constructs each type of JDOM document fragment, for the
31  * DOMFactory. The DOMBuilder has been separated from the DOMFactory to hide the
32  * implmentation of node creation and the public Requestor API methods.
33  * 
34  */
35
36 public class DOMBuilder extends AbstractDOMBuilder implements
37                 IDocumentElementRequestor {
38
39         /**
40          * True when parsing a single member - ignore any problems encountered after
41          * the member.
42          */
43         protected boolean fBuildingSingleMember = false;
44
45         /**
46          * True when the single member being built has been exited.
47          */
48         protected boolean fFinishedSingleMember = false;
49
50         /**
51          * Collection of multiple fields in one declaration
52          */
53         protected ArrayList fFields;
54
55         Map options = JavaCore.getOptions();
56
57         /**
58          * Creates a new DOMBuilder
59          */
60         public DOMBuilder() {
61         }
62
63         /**
64          * @see IDocumentElementRequestor#acceptImport(int declarationStart, int
65          *      declarationEnd, int[] javaDocPositions, char[] name, int
66          *      nameStartPosition, boolean onDemand)
67          */
68         public void acceptImport(int declarationStart, int declarationEnd,
69                         int[] javaDocPositions, char[] name, int nameStart, boolean onDemand) {
70                 int[] sourceRange = { declarationStart, declarationEnd };
71                 int[] nameRange = { nameStart, declarationEnd - 1 };
72
73                 /* See 1FVII1P */
74                 String importName = CharArrayOps.substring(fDocument, nameRange[0],
75                                 nameRange[1] + 1 - nameRange[0]);
76
77                 fNode = new DOMImport(fDocument, sourceRange, importName, nameRange,
78                                 onDemand);
79                 addChild(fNode);
80                 if (fBuildingSingleMember) {
81                         fFinishedSingleMember = true;
82                 }
83         }
84
85         /**
86          * @see IDocumentElementRequestor#acceptInitializer(int declarationStart,
87          *      int declarationEnd, int[] javaDocPositions, int modifiers, int
88          *      modifiersStart, int bodyStart, int bodyEnd)
89          */
90         public void acceptInitializer(int declarationStart, int declarationEnd,
91                         int[] javaDocPositions, int modifiers, int modifiersStart,
92                         int bodyStart, int bodyEnd) {
93                 int[] sourceRange = { declarationStart, declarationEnd };
94                 int[] commentRange = { -1, -1 };
95                 if (javaDocPositions != null) {
96                         int length = javaDocPositions.length;
97                         commentRange[0] = javaDocPositions[length - 2];
98                         commentRange[1] = javaDocPositions[length - 1];
99                 }
100
101                 int[] modifiersRange = { -1, -1 };
102                 if (modifiersStart > declarationStart) {
103                         modifiersRange[0] = modifiersStart;
104                         modifiersRange[1] = bodyStart - 1;
105                 }
106                 fNode = new DOMInitializer(fDocument, sourceRange, commentRange,
107                                 modifiers, modifiersRange, bodyStart);
108                 addChild(fNode);
109                 if (fBuildingSingleMember) {
110                         fFinishedSingleMember = true;
111                 }
112         }
113
114         /**
115          * @see IDocumentElementRequestor#acceptPackage(int declarationStart, int
116          *      declarationEnd, int[] javaDocPositions, char[] name, int
117          *      nameStartPosition)
118          */
119         public void acceptPackage(int declarationStart, int declarationEnd,
120                         int[] javaDocPositions, char[] name, int nameStartPosition) {
121                 int[] sourceRange = { declarationStart, declarationEnd };
122                 int[] nameRange = { nameStartPosition, declarationEnd - 1 };
123                 fNode = new DOMPackage(fDocument, sourceRange, CharArrayOps
124                                 .charToString(name), nameRange);
125                 addChild(fNode);
126                 if (fBuildingSingleMember) {
127                         fFinishedSingleMember = true;
128                 }
129         }
130
131         /**
132          * Sets the abort flag to true. The parser has encountered an error in the
133          * current document. If we are only building a single member, and we are
134          * done with the member - don't worry about the error.
135          * 
136          * @see IDocumentElementRequestor
137          */
138         public void acceptProblem(IProblem problem) {
139                 if (fBuildingSingleMember && fFinishedSingleMember) {
140                         return;
141                 }
142                 fAbort = true;
143         }
144
145         /**
146          * Adds the given node to the current enclosing scope, building the JDOM
147          * tree. Nodes are only added to an enclosing scope when a compilation unit
148          * or type is being built (since those are the only nodes that have
149          * children).
150          * 
151          * <p>
152          * NOTE: nodes are added to the JDOM via the method #basicAddChild such that
153          * the nodes in the newly created JDOM are not fragmented.
154          */
155         protected void addChild(IDOMNode child) {
156                 super.addChild(child);
157                 if (fStack.isEmpty() && fFields != null) {
158                         fFields.add(child);
159                 }
160         }
161
162         /**
163          * @see IDOMFactory#createCompilationUnit()
164          */
165         public IDOMCompilationUnit createCompilationUnit() {
166                 return new DOMCompilationUnit();
167         }
168
169         /**
170          * @see IDOMFactory#createCompilationUnit(String, String)
171          */
172         public IDOMCompilationUnit createCompilationUnit(
173                         ICompilationUnit compilationUnit) {
174                 initializeBuild(compilationUnit.getContents(), true, true, false);
175                 getParser(options).parseCompilationUnit(compilationUnit);
176                 return super.createCompilationUnit(compilationUnit);
177         }
178
179         /**
180          * @see IDOMFactory#createField(String)
181          */
182         // public IDOMField createField(char[] sourceCode) {
183         // initializeBuild(sourceCode, false, false, true);
184         // getParser(options).parseField(sourceCode);
185         // if (fAbort || fNode == null) {
186         // return null;
187         // }
188         //
189         // // we only accept field declarations with one field
190         // if (fFieldCount > 1) {
191         // return null;
192         // }
193         //      
194         // fNode.normalize(this);
195         // return (IDOMField)fNode;
196         // }
197         /**
198          * 
199          */
200         // public IDOMField[] createFields(char[] sourceCode) {
201         // initializeBuild(sourceCode, false, false, false);
202         // fFields= new ArrayList();
203         // getParser(options).parseField(sourceCode);
204         // if (fAbort) {
205         // return null;
206         // }
207         // IDOMField[] fields= new IDOMField[fFields.size()];
208         // fFields.toArray(fields);
209         // for (int i= 0; i < fields.length; i++) {
210         // DOMNode node= (DOMNode)fields[i];
211         // if (i < (fields.length - 1)) {
212         // DOMNode next= (DOMNode)fields[i + 1];
213         // node.fNextNode= next;
214         // next.fPreviousNode= node;
215         // }
216         // ((DOMNode)fields[i]).normalize(this);
217         // }
218         // return fields;
219         // }
220         /**
221          * @see IDOMFactory#createImport()
222          */
223         // public IDOMImport createImport() {
224         // return new DOMImport();
225         // }
226         /**
227          * @see IDOMFactory#createImport(String)
228          */
229         // public IDOMImport createImport(char[] sourceCode) {
230         // initializeBuild(sourceCode, false, false, true);
231         // getParser(options).parseImport(sourceCode);
232         // if (fAbort || fNode == null) {
233         // return null;
234         // }
235         // fNode.normalize(this);
236         // return (IDOMImport)fNode;
237         // }
238         /**
239          * Creates an INITIALIZER document fragment from the given source.
240          * 
241          * @see IDOMFactory#createInitializer(String)
242          */
243         // public IDOMInitializer createInitializer(char[] sourceCode) {
244         // initializeBuild(sourceCode, false, false, true);
245         // getParser(options).parseInitializer(sourceCode);
246         // if (fAbort || fNode == null || !(fNode instanceof IDOMInitializer)) {
247         // return null;
248         // }
249         // fNode.normalize(this);
250         // return (IDOMInitializer)fNode;
251         // }
252         /**
253          * @see IDOMFactory#createMethod(String)
254          */
255         // public IDOMMethod createMethod(char[] sourceCode) {
256         // initializeBuild(sourceCode, false, false, true);
257         // getParser(options).parseMethod(sourceCode);
258         // if (fAbort || fNode == null) {
259         // return null;
260         // }
261         // fNode.normalize(this);
262         // return (IDOMMethod)fNode;
263         // }
264         /**
265          * @see IDOMFactory#createPackage()
266          */
267         public IDOMPackage createPackage() {
268                 return new DOMPackage();
269         }
270
271         /**
272          * @see IDOMFactory#createPackage(String)
273          */
274         // public IDOMPackage createPackage(char[] sourceCode) {
275         // initializeBuild(sourceCode, false, false, true);
276         // getParser(options).parsePackage(sourceCode);
277         // if (fAbort || fNode == null) {
278         // return null;
279         // }
280         // fNode.normalize(this);
281         // return (IDOMPackage)fNode;
282         // }
283         /**
284          * @see IDOMFactory#createType(String)
285          */
286         // public IDOMType createType(char[] sourceCode) {
287         // initializeBuild(sourceCode, false, true, false);
288         // getParser(options).parseType(sourceCode);
289         // if (fAbort) {
290         // return null;
291         // }
292         // if (fNode != null) fNode.normalize(this);
293         // return (IDOMType)fNode;
294         // }
295         /**
296          * Creates a new DOMMethod and inizializes.
297          * 
298          * @param declarationStart -
299          *            a source position corresponding to the first character of this
300          *            constructor declaration
301          * @param modifiers -
302          *            the modifiers for this constructor converted to a flag
303          * @param modifiersStart -
304          *            a source position corresponding to the first character of the
305          *            textual modifiers
306          * @param returnType -
307          *            the name of the return type
308          * @param returnTypeStart -
309          *            a source position corresponding to the first character of the
310          *            return type
311          * @param returnTypeEnd -
312          *            a source position corresponding to the last character of the
313          *            return type
314          * @param returnTypeDimensionCount -
315          *            the array dimension count as supplied on the return type (for
316          *            instance, 'public int[] foo() {}')
317          * @param name -
318          *            the name of this constructor
319          * @param nameStart -
320          *            a source position corresponding to the first character of the
321          *            name
322          * @param nameEnd -
323          *            a source position corresponding to the last character of the
324          *            name
325          * @param parameterTypes -
326          *            a list of parameter type names
327          * @param parameterTypeStarts -
328          *            a list of source positions corresponding to the first
329          *            character of each parameter type name
330          * @param parameterTypeEnds -
331          *            a list of source positions corresponding to the last character
332          *            of each parameter type name
333          * @param parameterNames -
334          *            a list of the names of the parameters
335          * @param parametersEnd -
336          *            a source position corresponding to the last character of the
337          *            parameter list
338          * @extendedReturnTypeDimensionCount - the array dimension count as supplied
339          *                                   on the end of the parameter list (for
340          *                                   instance, 'public int foo()[] {}')
341          * @extendedReturnTypeDimensionEnd - a source position corresponding to the
342          *                                 last character of the extended return
343          *                                 type dimension
344          * @param exceptionTypes -
345          *            a list of the exception types
346          * @param exceptionTypeStarts -
347          *            a list of source positions corresponding to the first
348          *            character of the respective exception types
349          * @param exceptionTypeEnds -
350          *            a list of source positions corresponding to the last character
351          *            of the respective exception types
352          * @param bodyStart -
353          *            a source position corresponding to the start of this
354          *            constructor's body
355          */
356         protected void enterAbstractMethod(int declarationStart,
357                         int[] javaDocPositions, int modifiers, int modifiersStart,
358                         char[] returnType, int returnTypeStart, int returnTypeEnd,
359                         int returnTypeDimensionCount, char[] name, int nameStart,
360                         int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
361                         int[] parameterTypeEnds, char[][] parameterNames,
362                         int[] parameterNameStarts, int[] parameterNameEnds,
363                         int parametersEnd, int extendedReturnTypeDimensionCount,
364                         int extendedReturnTypeDimensionEnd, char[][] exceptionTypes,
365                         int[] exceptionTypeStarts, int[] exceptionTypeEnds, int bodyStart,
366                         boolean isConstructor) {
367                 int[] sourceRange = { declarationStart, -1 }; // will be fixed up on
368                                                                                                                 // exit
369                 int[] nameRange = { nameStart, nameEnd };
370                 int[] commentRange = { -1, -1 };
371                 if (javaDocPositions != null) {
372                         int length = javaDocPositions.length;
373                         commentRange[0] = javaDocPositions[0];
374                         commentRange[1] = javaDocPositions[length - 1];
375                 }
376                 int[] modifiersRange = { -1, -1 };
377                 if (modifiersStart > -1) {
378                         modifiersRange[0] = modifiersStart;
379                         if (isConstructor) {
380                                 modifiersRange[1] = nameStart - 1;
381                         } else {
382                                 modifiersRange[1] = returnTypeStart - 1;
383                         }
384                 }
385                 int[] returnTypeRange = null;
386
387                 if (extendedReturnTypeDimensionCount > 0)
388                         returnTypeRange = new int[] { returnTypeStart, returnTypeEnd,
389                                         parametersEnd + 1, extendedReturnTypeDimensionEnd };
390                 else
391                         returnTypeRange = new int[] { returnTypeStart, returnTypeEnd };
392                 int[] parameterRange = { nameEnd + 1, parametersEnd };
393                 int[] exceptionRange = { -1, -1 };
394                 if (exceptionTypes != null && exceptionTypes.length > 0) {
395                         int exceptionCount = exceptionTypes.length;
396                         exceptionRange[0] = exceptionTypeStarts[0];
397                         exceptionRange[1] = exceptionTypeEnds[exceptionCount - 1];
398                 }
399                 int[] bodyRange = null;
400                 if (exceptionRange[1] > -1) {
401                         bodyRange = new int[] { exceptionRange[1] + 1, -1 }; // will be
402                                                                                                                                         // fixed up
403                                                                                                                                         // on exit
404                 } else {
405                         bodyRange = new int[] { parametersEnd + 1, -1 };
406                 }
407                 fNode = new DOMMethod(fDocument, sourceRange, CharArrayOps
408                                 .charToString(name), nameRange, commentRange, modifiers,
409                                 modifiersRange, isConstructor, CharArrayOps
410                                                 .charToString(returnType), returnTypeRange,
411                                 CharArrayOps.charcharToString(parameterTypes), CharArrayOps
412                                                 .charcharToString(parameterNames), parameterRange,
413                                 CharArrayOps.charcharToString(exceptionTypes), exceptionRange,
414                                 bodyRange);
415                 addChild(fNode);
416                 fStack.push(fNode);
417         }
418
419         /**
420          * @see IDocumentElementRequestor#enterClass( int declarationStart, int[]
421          *      javaDocPositions, int modifiers, int modifiersStart, int classStart,
422          *      char[] name, int nameStart, int nameEnd, char[] superclass, int
423          *      superclassStart, int superclassEnd, char[][] superinterfaces, int[]
424          *      superinterfaceStarts, int[] superinterfaceEnds, int bodyStart)
425          */
426         public void enterClass(int declarationStart, int[] javaDocPositions,
427                         int modifiers, int modifiersStart, int keywordStart, char[] name,
428                         int nameStart, int nameEnd, char[] superclass, int superclassStart,
429                         int superclassEnd, char[][] superinterfaces,
430                         int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) {
431
432                 enterType(declarationStart, javaDocPositions, modifiers,
433                                 modifiersStart, keywordStart, name, nameStart, nameEnd,
434                                 superclass, superclassStart, superclassEnd, superinterfaces,
435                                 superinterfaceStarts, superinterfaceEnds, bodyStart, true);
436         }
437
438         /**
439          * @see IDocumentElementRequestor#enterConstructor( int declarationStart,
440          *      int[] javaDocPositions, int modifiers, int modifiersStart, char[]
441          *      name, int nameStart, int nameEnd, char[][] parameterTypes, int []
442          *      parameterTypeStarts, int [] parameterTypeEnds, char[][]
443          *      parameterNames, int [] parameterNameStarts, int []
444          *      parameterNameEnds, int parametersEnd, char[][] exceptionTypes, int []
445          *      exceptionTypeStarts, int [] exceptionTypeEnds, int bodyStart)
446          */
447         public void enterConstructor(int declarationStart, int[] javaDocPositions,
448                         int modifiers, int modifiersStart, char[] name, int nameStart,
449                         int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
450                         int[] parameterTypeEnds, char[][] parameterNames,
451                         int[] parameterNameStarts, int[] parameterNameEnds,
452                         int parametersEnd, char[][] exceptionTypes,
453                         int[] exceptionTypeStarts, int[] exceptionTypeEnds, int bodyStart) {
454
455                 /* see 1FVIIQZ */
456                 String nameString = new String(fDocument, nameStart, nameEnd
457                                 - nameStart);
458                 int openParenPosition = nameString.indexOf('(');
459                 if (openParenPosition > -1)
460                         nameEnd = nameStart + openParenPosition - 1;
461
462                 enterAbstractMethod(declarationStart, javaDocPositions, modifiers,
463                                 modifiersStart, null, -1, -1, 0, name, nameStart, nameEnd,
464                                 parameterTypes, parameterTypeStarts, parameterTypeEnds,
465                                 parameterNames, parameterNameStarts, parameterNameEnds,
466                                 parametersEnd, 0, -1, exceptionTypes, exceptionTypeStarts,
467                                 exceptionTypeEnds, bodyStart, true);
468         }
469
470         /**
471          * @see IDocumentElementRequestor#enterField( int declarationStart, int[]
472          *      javaDocPositions, int modifiers, int modifiersStart, char[] type,
473          *      int typeStart, int typeEnd, int typeDimensionCount, char[] name, int
474          *      nameStart, int nameEnd, int extendedTypeDimensionCount, int
475          *      extendedTypeDimensionEnd)
476          */
477         public void enterField(int declarationStart, int[] javaDocPositions,
478                         int modifiers, int modifiersStart, char[] type, int typeStart,
479                         int typeEnd, int typeDimensionCount, char[] name, int nameStart,
480                         int nameEnd, int extendedTypeDimensionCount,
481                         int extendedTypeDimensionEnd) {
482                 int[] sourceRange = {
483                                 declarationStart,
484                                 (extendedTypeDimensionEnd > nameEnd) ? extendedTypeDimensionEnd
485                                                 : nameEnd };
486                 int[] nameRange = { nameStart, nameEnd };
487                 int[] commentRange = { -1, -1 };
488                 if (javaDocPositions != null) {
489                         int length = javaDocPositions.length;
490                         commentRange[0] = javaDocPositions[0];
491                         commentRange[1] = javaDocPositions[length - 1];
492                 }
493                 int[] modifiersRange = { -1, -1 };
494                 if (modifiersStart > -1) {
495                         modifiersRange[0] = modifiersStart;
496                         modifiersRange[1] = typeStart - 1;
497                 }
498                 int[] typeRange = { typeStart, typeEnd };
499                 boolean hasInitializer = false; // fixed on exitField
500                 int[] initializerRange = { -1, -1 }; // fixed on exitField
501                 boolean isVariableDeclarator = false;
502                 if (fNode instanceof DOMField) {
503                         DOMField field = (DOMField) fNode;
504                         if (field.fTypeRange[0] == typeStart)
505                                 isVariableDeclarator = true;
506                 }
507                 fNode = new DOMField(fDocument, sourceRange, CharArrayOps
508                                 .charToString(name), nameRange, commentRange, modifiers,
509                                 modifiersRange, typeRange, CharArrayOps.charToString(type),
510                                 hasInitializer, initializerRange, isVariableDeclarator);
511                 addChild(fNode);
512                 fStack.push(fNode);
513         }
514
515         /**
516          * @see IDocumentElementRequestor#enterInterface( int declarationStart,
517          *      int[] javaDocPositions, int modifiers, int modifiersStart, int
518          *      interfaceStart, char[] name, int nameStart, int nameEnd, char[][]
519          *      superinterfaces, int[] superinterfaceStarts, int[]
520          *      superinterfaceEnds, int bodyStart)
521          */
522         public void enterInterface(int declarationStart, int[] javaDocPositions,
523                         int modifiers, int modifiersStart, int keywordStart, char[] name,
524                         int nameStart, int nameEnd, char[][] superinterfaces,
525                         int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) {
526
527                 enterType(declarationStart, javaDocPositions, modifiers,
528                                 modifiersStart, keywordStart, name, nameStart, nameEnd, null,
529                                 -1, -1, superinterfaces, superinterfaceStarts,
530                                 superinterfaceEnds, bodyStart, false);
531         }
532
533         /**
534          * @see IDocumentElementRequestor#enterMethod( int declarationStart, int[]
535          *      javaDocPositions, int modifiers, int modifiersStart, char[]
536          *      returnType, int returnTypeStart, int returnTypeEnd, int
537          *      returnTypeDimensionCount, char[] name, int nameStart, int nameEnd,
538          *      char[][] parameterTypes, int [] parameterTypeStarts, int []
539          *      parameterTypeEnds, char[][] parameterNames, int []
540          *      parameterNameStarts, int [] parameterNameEnds, int parametersEnd,
541          *      int extendedReturnTypeDimensionCount, int
542          *      extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int []
543          *      exceptionTypeStarts, int [] exceptionTypeEnds, int bodyStart)
544          */
545         public void enterMethod(int declarationStart, int[] javaDocPositions,
546                         int modifiers, int modifiersStart, char[] returnType,
547                         int returnTypeStart, int returnTypeEnd,
548                         int returnTypeDimensionCount, char[] name, int nameStart,
549                         int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts,
550                         int[] parameterTypeEnds, char[][] parameterNames,
551                         int[] parameterNameStarts, int[] parameterNameEnds,
552                         int parametersEnd, int extendedReturnTypeDimensionCount,
553                         int extendedReturnTypeDimensionEnd, char[][] exceptionTypes,
554                         int[] exceptionTypeStarts, int[] exceptionTypeEnds, int bodyStart) {
555                 enterAbstractMethod(declarationStart, javaDocPositions, modifiers,
556                                 modifiersStart, returnType, returnTypeStart, returnTypeEnd,
557                                 returnTypeDimensionCount, name, nameStart, nameEnd,
558                                 parameterTypes, parameterTypeStarts, parameterTypeEnds,
559                                 parameterNames, parameterNameStarts, parameterNameEnds,
560                                 parametersEnd, extendedReturnTypeDimensionCount,
561                                 extendedReturnTypeDimensionEnd, exceptionTypes,
562                                 exceptionTypeStarts, exceptionTypeEnds, bodyStart, false);
563         }
564
565         protected void enterType(int declarationStart, int[] javaDocPositions,
566                         int modifiers, int modifiersStart, int keywordStart, char[] name,
567                         int nameStart, int nameEnd, char[] superclass, int superclassStart,
568                         int superclassEnd, char[][] superinterfaces,
569                         int[] superinterfaceStarts, int[] superinterfaceEnds,
570                         int bodyStart, boolean isClass) {
571                 if (fBuildingType) {
572                         int[] sourceRange = { declarationStart, -1 }; // will be fixed in
573                                                                                                                         // the exit
574                         int[] commentRange = { -1, -1 };
575                         if (javaDocPositions != null) {
576                                 int length = javaDocPositions.length;
577                                 commentRange[0] = javaDocPositions[0];
578                                 commentRange[1] = javaDocPositions[length - 1];
579                         }
580                         int[] modifiersRange = { -1, -1 };
581                         if (modifiersStart > -1) {
582                                 modifiersRange[0] = modifiersStart;
583                                 modifiersRange[1] = (modifiersStart > -1) ? keywordStart - 1
584                                                 : -1;
585                         }
586                         int[] typeKeywordRange = { keywordStart, nameStart - 1 };
587                         int[] nameRange = new int[] { nameStart, nameEnd };
588                         int[] extendsKeywordRange = { -1, -1 };
589                         int[] superclassRange = { -1, -1 };
590                         int[] implementsKeywordRange = { -1, -1 };
591                         int[] interfacesRange = { -1, -1 };
592                         if (isClass) {
593                                 if (superclass != null) {
594                                         extendsKeywordRange[0] = nameEnd + 1;
595                                         extendsKeywordRange[1] = superclassStart - 1;
596                                         superclassRange[0] = superclassStart;
597                                         superclassRange[1] = bodyStart - 1;
598                                 }
599                                 if (superinterfaces != null && superinterfaces.length > 0) {
600                                         superclassRange[1] = superclassEnd;
601                                         if (superclassEnd > -1) {
602                                                 implementsKeywordRange[0] = superclassEnd + 1;
603                                         } else {
604                                                 implementsKeywordRange[0] = nameEnd + 1;
605                                         }
606                                         implementsKeywordRange[1] = superinterfaceStarts[0] - 1;
607                                         interfacesRange[0] = superinterfaceStarts[0];
608                                         interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
609                                 }
610                         } else {
611                                 if (superinterfaces != null && superinterfaces.length > 0) {
612                                         extendsKeywordRange[0] = nameEnd + 1;
613                                         extendsKeywordRange[1] = superinterfaceStarts[0] - 1;
614                                         interfacesRange[0] = superinterfaceStarts[0];
615                                         interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
616                                 }
617                         }
618                         int[] openBodyRange = { bodyStart, -1 }; // fixed by
619                                                                                                                 // setTypeRanges(DOMNode)
620                         int[] closeBodyRange = { -1, -1 }; // will be fixed in exit
621                         fNode = new DOMType(fDocument, sourceRange, new String(name),
622                                         nameRange, commentRange, modifiers, modifiersRange,
623                                         typeKeywordRange, superclassRange, extendsKeywordRange,
624                                         CharArrayOps.charcharToString(superinterfaces),
625                                         interfacesRange, implementsKeywordRange, openBodyRange,
626                                         closeBodyRange, isClass);
627                         addChild(fNode);
628                         fStack.push(fNode);
629                 }
630         }
631
632         /**
633          * Finishes the configuration of the constructors and methods.
634          * 
635          * @param bodyEnd -
636          *            a source position corresponding to the closing bracket of the
637          *            method
638          * @param declarationEnd -
639          *            a source position corresponding to the end of the method
640          *            declaration. This can include whitespace and comments
641          *            following the closing bracket.
642          */
643         protected void exitAbstractMethod(int bodyEnd, int declarationEnd) {
644                 DOMMethod method = (DOMMethod) fStack.pop();
645                 method.setSourceRangeEnd(declarationEnd);
646                 method.setBodyRangeEnd(bodyEnd + 1);
647                 fNode = method;
648                 if (fBuildingSingleMember) {
649                         fFinishedSingleMember = true;
650                 }
651         }
652
653         /**
654          * Finishes the configuration of the class DOM object which was created by a
655          * previous enterClass call.
656          * 
657          * @see IDocumentElementRequestor#exitClass(int, int)
658          */
659         public void exitClass(int bodyEnd, int declarationEnd) {
660                 exitType(bodyEnd, declarationEnd);
661         }
662
663         /**
664          * Finishes the configuration of the method DOM object which was created by
665          * a previous enterConstructor call.
666          * 
667          * @see IDocumentElementRequestor#exitConstructor(int, int)
668          */
669         public void exitConstructor(int bodyEnd, int declarationEnd) {
670                 exitAbstractMethod(bodyEnd, declarationEnd);
671         }
672
673         /**
674          * Finishes the configuration of the field DOM object which was created by a
675          * previous enterField call.
676          * 
677          * @see IDocumentElementRequestor#exitField(int, int)
678          */
679         public void exitField(int bodyEnd, int declarationEnd) {
680                 DOMField field = (DOMField) fStack.pop();
681                 if (field.getEndPosition() < declarationEnd) {
682                         field.setSourceRangeEnd(declarationEnd);
683                         int nameEnd = field.fNameRange[1];
684                         if (nameEnd < bodyEnd) {
685                                 /* see 1FVIIV8 - obtain initializer range */
686                                 String initializer = new String(fDocument, nameEnd + 1, bodyEnd
687                                                 - nameEnd);
688                                 int index = initializer.indexOf('=');
689                                 if (index > -1) {
690                                         field.setHasInitializer(true);
691                                         field.setInitializerRange(nameEnd + index + 2, bodyEnd);
692                                 }
693                         }
694                 }
695                 fFieldCount++;
696                 fNode = field;
697                 if (fBuildingSingleMember) {
698                         fFinishedSingleMember = true;
699                 }
700         }
701
702         /**
703          * Finishes the configuration of the interface DOM object which was created
704          * by a previous enterInterface call.
705          * 
706          * @see IDocumentElementRequestor#exitInterface(int, int)
707          */
708         public void exitInterface(int bodyEnd, int declarationEnd) {
709                 exitType(bodyEnd, declarationEnd);
710         }
711
712         /**
713          * Finishes the configuration of the method DOM object which was created by
714          * a previous enterMethod call.
715          * 
716          * @see IDocumentElementRequestor#exitMethod(int, int)
717          */
718         public void exitMethod(int bodyEnd, int declarationEnd) {
719                 exitAbstractMethod(bodyEnd, declarationEnd);
720         }
721
722         /**
723          * Creates a new parser.
724          */
725         protected DocumentElementParser getParser(Map settings) {
726                 return new DocumentElementParser(this, new DefaultProblemFactory(),
727                                 new CompilerOptions(settings));
728         }
729
730         /**
731          * Initializes the builder to create a document fragment.
732          * 
733          * @param sourceCode -
734          *            the document containing the source code to be analyzed
735          * @param buildingCompilationUnit -
736          *            true if a the document is being analyzed to create a
737          *            compilation unit, otherwise false
738          * @param buildingType -
739          *            true if the document is being analyzed to create a type or
740          *            compilation unit
741          * @param singleMember -
742          *            true if building a single member
743          */
744         protected void initializeBuild(char[] sourceCode,
745                         boolean buildingCompilationUnit, boolean buildingType,
746                         boolean singleMember) {
747                 super
748                                 .initializeBuild(sourceCode, buildingCompilationUnit,
749                                                 buildingType);
750                 fBuildingSingleMember = singleMember;
751                 fFinishedSingleMember = false;
752
753         }
754 }