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