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