new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / jdom / DOMBuilder.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMBuilder.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMBuilder.java
new file mode 100644 (file)
index 0000000..f1faf41
--- /dev/null
@@ -0,0 +1,713 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2003 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials 
+ * are made available under the terms of the Common Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/cpl-v10.html
+ * 
+ * Contributors:
+ *     IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package net.sourceforge.phpdt.internal.core.jdom;
+
+import java.util.ArrayList;
+import java.util.Map;
+
+import net.sourceforge.phpdt.core.compiler.IProblem;
+import net.sourceforge.phpdt.core.jdom.IDOMCompilationUnit;
+import net.sourceforge.phpdt.core.jdom.IDOMField;
+import net.sourceforge.phpdt.core.jdom.IDOMImport;
+import net.sourceforge.phpdt.core.jdom.IDOMInitializer;
+import net.sourceforge.phpdt.core.jdom.IDOMMethod;
+import net.sourceforge.phpdt.core.jdom.IDOMNode;
+import net.sourceforge.phpdt.core.jdom.IDOMPackage;
+import net.sourceforge.phpdt.core.jdom.IDOMType;
+import net.sourceforge.phpdt.internal.compiler.DocumentElementParser;
+import net.sourceforge.phpdt.internal.compiler.IDocumentElementRequestor;
+import net.sourceforge.phpdt.internal.compiler.env.ICompilationUnit;
+import net.sourceforge.phpdt.internal.compiler.problem.DefaultProblemFactory;
+import net.sourceforge.phpdt.internal.core.util.CharArrayOps;
+import net.sourceforge.phpeclipse.PHPCore;
+
+/**
+ * The DOMBuilder constructs each type of JDOM document fragment,
+ * for the DOMFactory. The DOMBuilder has been separated from the
+ * DOMFactory to hide the implmentation of node creation and the
+ * public Requestor API methods.
+ * 
+ */
+
+public class DOMBuilder extends AbstractDOMBuilder implements IDocumentElementRequestor {
+       
+       /**
+        * True when parsing a single member - ignore any problems
+        * encountered after the member.
+        */
+       protected boolean fBuildingSingleMember= false;
+       
+       /**
+        * True when the single member being built has been
+        * exited.
+        */
+       protected boolean fFinishedSingleMember = false;                
+
+       /**
+        * Collection of multiple fields in one declaration
+        */
+       protected ArrayList fFields;
+
+       Map options = PHPCore.getOptions();
+
+/**
+ * Creates a new DOMBuilder
+ */
+public DOMBuilder() {}
+/**
+ * @see IDocumentElementRequestor#acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition, boolean onDemand)
+ */
+public void acceptImport(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, 
+       int nameStart, boolean onDemand) {
+       int[] sourceRange = {declarationStart, declarationEnd};
+       int[] nameRange = {nameStart, declarationEnd - 1};
+       
+       /* See 1FVII1P */
+       String importName = CharArrayOps.substring(fDocument, nameRange[0], nameRange[1] + 1 - nameRange[0]);
+
+       fNode= new DOMImport(fDocument, sourceRange, importName, nameRange, onDemand);
+       addChild(fNode);
+       if (fBuildingSingleMember) {
+               fFinishedSingleMember= true;
+       }
+}
+/**
+ * @see IDocumentElementRequestor#acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, int modifiersStart, int bodyStart, int bodyEnd)
+ */
+public void acceptInitializer(int declarationStart, int declarationEnd, int[] javaDocPositions, int modifiers, 
+       int modifiersStart, int bodyStart, int bodyEnd) {
+       int[] sourceRange = {declarationStart, declarationEnd};
+       int[] commentRange = {-1, -1};
+       if (javaDocPositions != null) {
+               int length = javaDocPositions.length;
+               commentRange[0] = javaDocPositions[length - 2];
+               commentRange[1] = javaDocPositions[length - 1];
+       }
+
+       int[] modifiersRange = {-1, -1};
+       if (modifiersStart > declarationStart) {
+               modifiersRange[0] = modifiersStart;
+               modifiersRange[1] = bodyStart - 1;
+       }
+       fNode = new DOMInitializer(fDocument, sourceRange, commentRange, modifiers, 
+               modifiersRange, bodyStart);
+       addChild(fNode);
+       if (fBuildingSingleMember) {
+               fFinishedSingleMember= true;
+       }
+}
+/**
+ * @see IDocumentElementRequestor#acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, int nameStartPosition)
+ */
+public void acceptPackage(int declarationStart, int declarationEnd, int[] javaDocPositions, char[] name, 
+       int nameStartPosition) {
+       int[] sourceRange = {declarationStart, declarationEnd};
+       int[] nameRange = {nameStartPosition, declarationEnd - 1};
+       fNode= new DOMPackage(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange);
+       addChild(fNode);
+       if (fBuildingSingleMember) {
+               fFinishedSingleMember= true;
+       }
+}
+/**
+ * Sets the abort flag to true. The parser has encountered an error
+ * in the current document. If we are only building a single member, and
+ * we are done with the member - don't worry about the error.
+ *
+ * @see IDocumentElementRequestor
+ */
+public void acceptProblem(IProblem problem){
+       if (fBuildingSingleMember && fFinishedSingleMember) {
+               return;
+       }
+       fAbort= true;
+}
+/**
+ * Adds the given node to the current enclosing scope, building the JDOM
+ * tree. Nodes are only added to an enclosing scope when a compilation unit or type
+ * is being built (since those are the only nodes that have children).
+ *
+ * <p>NOTE: nodes are added to the JDOM via the method #basicAddChild such that
+ * the nodes in the newly created JDOM are not fragmented. 
+ */
+protected void addChild(IDOMNode child) {
+       super.addChild(child);
+       if (fStack.isEmpty() && fFields != null) {
+               fFields.add(child);
+       }
+}
+/**
+ * @see IDOMFactory#createCompilationUnit()
+ */
+public IDOMCompilationUnit createCompilationUnit() {
+       return new DOMCompilationUnit();
+}
+/**
+ * @see IDOMFactory#createCompilationUnit(String, String)
+ */
+public IDOMCompilationUnit createCompilationUnit(ICompilationUnit compilationUnit) {
+       initializeBuild(compilationUnit.getContents(), true, true, false);
+       getParser(options).parseCompilationUnit(compilationUnit);
+       return super.createCompilationUnit(compilationUnit);
+}
+/**
+ * @see IDOMFactory#createField(String)
+ */
+//public IDOMField createField(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, false, true);
+//     getParser(options).parseField(sourceCode);
+//     if (fAbort || fNode == null) {
+//             return null;
+//     }
+//
+//     // we only accept field declarations with one field
+//     if (fFieldCount > 1) {
+//             return null;
+//     }
+//     
+//     fNode.normalize(this);
+//     return (IDOMField)fNode;
+//}
+/**
+ * 
+ */
+//public IDOMField[] createFields(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, false, false);
+//     fFields= new ArrayList();
+//     getParser(options).parseField(sourceCode);
+//     if (fAbort) {
+//             return null;
+//     }
+//     IDOMField[] fields= new IDOMField[fFields.size()];
+//     fFields.toArray(fields);
+//     for (int i= 0; i < fields.length; i++) {
+//             DOMNode node= (DOMNode)fields[i];
+//             if (i < (fields.length - 1)) {
+//                     DOMNode next= (DOMNode)fields[i + 1];
+//                     node.fNextNode= next;
+//                     next.fPreviousNode= node;
+//             }
+//             ((DOMNode)fields[i]).normalize(this);
+//     }
+//     return fields;
+//}
+/**
+ * @see IDOMFactory#createImport()
+ */
+//public IDOMImport createImport() {
+//     return new DOMImport();
+//}
+/**
+ * @see IDOMFactory#createImport(String)
+ */
+//public IDOMImport createImport(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, false, true);
+//     getParser(options).parseImport(sourceCode);
+//     if (fAbort || fNode == null) {
+//             return null;
+//     }
+//     fNode.normalize(this);
+//     return (IDOMImport)fNode;
+//}
+/**
+ * Creates an INITIALIZER document fragment from the given source.
+ *
+ * @see IDOMFactory#createInitializer(String)
+ */
+//public IDOMInitializer createInitializer(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, false, true);
+//     getParser(options).parseInitializer(sourceCode);
+//     if (fAbort || fNode == null || !(fNode instanceof IDOMInitializer)) {
+//             return null;
+//     }
+//     fNode.normalize(this);
+//     return (IDOMInitializer)fNode;
+//}
+/**
+ * @see IDOMFactory#createMethod(String)
+ */
+//public IDOMMethod createMethod(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, false, true);
+//     getParser(options).parseMethod(sourceCode);
+//     if (fAbort || fNode == null) {
+//             return null;
+//     }
+//     fNode.normalize(this);
+//     return (IDOMMethod)fNode;
+//}
+/**
+ * @see IDOMFactory#createPackage()
+ */
+public IDOMPackage createPackage() {
+       return new DOMPackage();
+}
+/**
+ * @see IDOMFactory#createPackage(String)
+ */
+//public IDOMPackage createPackage(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, false, true);
+//     getParser(options).parsePackage(sourceCode);
+//     if (fAbort || fNode == null) {
+//             return null;
+//     }
+//     fNode.normalize(this);
+//     return (IDOMPackage)fNode;
+//}
+/**
+ * @see IDOMFactory#createType(String)
+ */
+//public IDOMType createType(char[] sourceCode) {
+//     initializeBuild(sourceCode, false, true, false);
+//     getParser(options).parseType(sourceCode);
+//     if (fAbort) {
+//             return null;
+//     }
+//     if (fNode != null) fNode.normalize(this);
+//     return (IDOMType)fNode;
+//}
+/**
+ * Creates a new DOMMethod and inizializes.
+ *
+ * @param declarationStart - a source position corresponding to the first character 
+ *             of this constructor declaration
+ * @param modifiers - the modifiers for this constructor converted to a flag
+ * @param modifiersStart - a source position corresponding to the first character of the
+ *             textual modifiers
+ * @param returnType - the name of the return type
+ * @param returnTypeStart - a source position corresponding to the first character
+ *             of the return type
+ * @param returnTypeEnd - a source position corresponding to the last character
+ *             of the return type
+ * @param returnTypeDimensionCount - the array dimension count as supplied on the
+ *             return type (for instance, 'public int[] foo() {}')
+ * @param name - the name of this constructor
+ * @param nameStart - a source position corresponding to the first character of the name
+ * @param nameEnd - a source position corresponding to the last character of the name
+ * @param parameterTypes - a list of parameter type names
+ * @param parameterTypeStarts - a list of source positions corresponding to the
+ *             first character of each parameter type name
+ * @param parameterTypeEnds - a list of source positions corresponding to the
+ *             last character of each parameter type name
+ * @param parameterNames - a list of the names of the parameters
+ * @param parametersEnd - a source position corresponding to the last character of the
+ *             parameter list
+ * @extendedReturnTypeDimensionCount - the array dimension count as supplied on the
+ *             end of the parameter list (for instance, 'public int foo()[] {}')
+ * @extendedReturnTypeDimensionEnd - a source position corresponding to the last character
+ *             of the extended return type dimension
+ * @param exceptionTypes - a list of the exception types
+ * @param exceptionTypeStarts - a list of source positions corresponding to the first
+ *             character of the respective exception types
+ * @param exceptionTypeEnds - a list of source positions corresponding to the last
+ *             character of the respective exception types
+ * @param bodyStart - a source position corresponding to the start of this 
+ *             constructor's body
+ */
+protected void enterAbstractMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
+       char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, 
+       char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, 
+       int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, 
+       int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, 
+       int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, 
+       int[] exceptionTypeEnds, int bodyStart, boolean isConstructor) {
+       int[] sourceRange = {declarationStart, -1}; // will be fixed up on exit
+       int[] nameRange = {nameStart, nameEnd};
+       int[] commentRange = {-1, -1};
+       if (javaDocPositions != null) {
+               int length = javaDocPositions.length;
+               commentRange[0] = javaDocPositions[0];
+               commentRange[1] = javaDocPositions[length - 1];
+       }
+       int[] modifiersRange = {-1, -1};
+       if (modifiersStart > -1) {
+               modifiersRange[0] = modifiersStart;
+               if (isConstructor) {
+                       modifiersRange[1] = nameStart - 1;
+               } else {
+                       modifiersRange[1] = returnTypeStart - 1;
+               }
+       }
+       int[] returnTypeRange = null;
+       
+       if (extendedReturnTypeDimensionCount > 0)
+               returnTypeRange = new int[] {returnTypeStart, returnTypeEnd, 
+                       parametersEnd + 1, extendedReturnTypeDimensionEnd};
+       else
+               returnTypeRange = new int[] {returnTypeStart, returnTypeEnd};
+       int[] parameterRange = {nameEnd + 1, parametersEnd};
+       int[] exceptionRange = {-1, -1};
+       if (exceptionTypes != null && exceptionTypes.length > 0) {
+               int exceptionCount = exceptionTypes.length;
+               exceptionRange[0] = exceptionTypeStarts[0];
+               exceptionRange[1] = exceptionTypeEnds[exceptionCount - 1];
+       }
+       int[] bodyRange = null;
+       if (exceptionRange[1] > -1) {
+               bodyRange = new int[] {exceptionRange[1] + 1, -1}; // will be fixed up on exit
+       } else {
+               bodyRange = new int[] {parametersEnd + 1, -1};
+       }
+       fNode = new DOMMethod(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, commentRange, modifiers, 
+               modifiersRange, isConstructor, CharArrayOps.charToString(returnType), returnTypeRange,
+               CharArrayOps.charcharToString(parameterTypes),
+               CharArrayOps.charcharToString(parameterNames), 
+               parameterRange, CharArrayOps.charcharToString(exceptionTypes), exceptionRange, bodyRange);
+       addChild(fNode);
+       fStack.push(fNode);
+}
+/**
+ * @see IDocumentElementRequestor#enterClass(
+       int declarationStart,
+       int[] javaDocPositions,
+       int modifiers,
+       int modifiersStart,
+       int classStart, 
+       char[] name,
+       int nameStart,
+       int nameEnd,
+       char[] superclass,
+       int superclassStart,
+       int superclassEnd,
+       char[][] superinterfaces,
+       int[] superinterfaceStarts,
+       int[] superinterfaceEnds,
+       int bodyStart)
+ */
+public void enterClass(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart, 
+       char[] name, int nameStart, int nameEnd, char[] superclass, int superclassStart, 
+       int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, 
+       int[] superinterfaceEnds, int bodyStart) {
+
+       enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
+               name, nameStart, nameEnd, superclass, superclassStart, 
+               superclassEnd, superinterfaces, superinterfaceStarts, 
+               superinterfaceEnds, bodyStart, true);
+}
+/**
+ * @see IDocumentElementRequestor#enterConstructor(
+       int declarationStart,
+       int[] javaDocPositions, 
+       int modifiers,
+       int modifiersStart, 
+       char[] name,
+       int nameStart,
+       int nameEnd,
+       char[][] parameterTypes,
+       int [] parameterTypeStarts,
+       int [] parameterTypeEnds,                       
+       char[][] parameterNames,
+       int [] parameterNameStarts,
+       int [] parameterNameEnds,
+       int parametersEnd,      
+       char[][] exceptionTypes,
+       int [] exceptionTypeStarts,
+       int [] exceptionTypeEnds,
+       int bodyStart)
+ */
+public void enterConstructor(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
+       char[] name, int nameStart, int nameEnd, char[][] parameterTypes, 
+       int[] parameterTypeStarts, int[] parameterTypeEnds, char[][] parameterNames, 
+       int[] parameterNameStarts, int[] parameterNameEnds, int parametersEnd, 
+       char[][] exceptionTypes, int[] exceptionTypeStarts, int[] exceptionTypeEnds, 
+       int bodyStart) {
+               
+       /* see 1FVIIQZ */
+       String nameString = new String(fDocument, nameStart, nameEnd - nameStart);
+       int openParenPosition = nameString.indexOf('(');
+       if (openParenPosition > -1)
+               nameEnd = nameStart + openParenPosition - 1;
+               
+       enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart, 
+               null, -1, -1, 0, 
+               name, nameStart, nameEnd, parameterTypes, parameterTypeStarts, 
+               parameterTypeEnds, parameterNames, parameterNameStarts, 
+               parameterNameEnds, parametersEnd, 0, 
+               -1, exceptionTypes, exceptionTypeStarts, 
+               exceptionTypeEnds, bodyStart,true);
+}
+/**
+ * @see IDocumentElementRequestor#enterField(
+       int declarationStart,
+       int[] javaDocPositions, 
+       int modifiers,
+       int modifiersStart,
+       char[] type,
+       int typeStart,
+       int typeEnd,
+       int typeDimensionCount,
+       char[] name,
+       int nameStart,
+       int nameEnd,
+       int extendedTypeDimensionCount,
+       int extendedTypeDimensionEnd)
+ */
+public void enterField(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
+       char[] type, int typeStart, int typeEnd, int typeDimensionCount, char[] name, 
+       int nameStart, int nameEnd, int extendedTypeDimensionCount, 
+       int extendedTypeDimensionEnd) {
+       int[] sourceRange = {declarationStart, 
+               (extendedTypeDimensionEnd > nameEnd) ? extendedTypeDimensionEnd : nameEnd};
+       int[] nameRange = {nameStart, nameEnd};
+       int[] commentRange = {-1, -1};
+               if (javaDocPositions != null) {
+                       int length = javaDocPositions.length;
+                       commentRange[0] = javaDocPositions[0];
+                       commentRange[1] = javaDocPositions[length - 1];
+               }
+       int[] modifiersRange = {-1, -1};
+       if (modifiersStart > -1) {
+               modifiersRange[0] = modifiersStart;
+               modifiersRange[1] = typeStart - 1;
+       }
+       int[] typeRange = {typeStart, typeEnd};
+       boolean hasInitializer = false; // fixed on exitField
+       int[] initializerRange = {-1, -1}; // fixed on exitField
+       boolean isVariableDeclarator = false;
+       if (fNode instanceof DOMField) {
+               DOMField field = (DOMField)fNode;
+               if (field.fTypeRange[0] == typeStart)
+                       isVariableDeclarator = true;
+       }       
+       fNode = new DOMField(fDocument, sourceRange, CharArrayOps.charToString(name), nameRange, commentRange, 
+               modifiers, modifiersRange, typeRange, CharArrayOps.charToString(type), hasInitializer, 
+               initializerRange, isVariableDeclarator);
+       addChild(fNode);
+       fStack.push(fNode);
+}
+/**
+ * @see IDocumentElementRequestor#enterInterface(
+       int declarationStart,
+       int[] javaDocPositions, 
+       int modifiers,
+       int modifiersStart,
+       int interfaceStart,
+       char[] name,
+       int nameStart,
+       int nameEnd,
+       char[][] superinterfaces,
+       int[] superinterfaceStarts,
+       int[] superinterfaceEnds,
+       int bodyStart)
+ */
+public void enterInterface(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, int keywordStart,
+       char[] name, int nameStart, int nameEnd, char[][] superinterfaces, 
+       int[] superinterfaceStarts, int[] superinterfaceEnds, int bodyStart) {
+
+       enterType(declarationStart, javaDocPositions, modifiers, modifiersStart, keywordStart,
+               name, nameStart, nameEnd, null, -1, -1, superinterfaces, 
+               superinterfaceStarts, superinterfaceEnds, bodyStart, false);
+}
+/**
+ * @see IDocumentElementRequestor#enterMethod(
+       int declarationStart,
+       int[] javaDocPositions, 
+       int modifiers,
+       int modifiersStart, 
+       char[] returnType,
+       int returnTypeStart,
+       int returnTypeEnd,
+       int returnTypeDimensionCount,
+       char[] name,
+       int nameStart,
+       int nameEnd,
+       char[][] parameterTypes,
+       int [] parameterTypeStarts,
+       int [] parameterTypeEnds,                       
+       char[][] parameterNames,
+       int [] parameterNameStarts,
+       int [] parameterNameEnds,
+       int parametersEnd,
+       int extendedReturnTypeDimensionCount,
+       int extendedReturnTypeDimensionEnd,     
+       char[][] exceptionTypes,
+       int [] exceptionTypeStarts,
+       int [] exceptionTypeEnds,
+       int bodyStart)
+ */
+public void enterMethod(int declarationStart, int[] javaDocPositions, int modifiers, int modifiersStart, 
+       char[] returnType, int returnTypeStart, int returnTypeEnd, int returnTypeDimensionCount, 
+       char[] name, int nameStart, int nameEnd, char[][] parameterTypes, int[] parameterTypeStarts, 
+       int[] parameterTypeEnds, char[][] parameterNames, int[] parameterNameStarts, 
+       int[] parameterNameEnds, int parametersEnd, int extendedReturnTypeDimensionCount, 
+       int extendedReturnTypeDimensionEnd, char[][] exceptionTypes, int[] exceptionTypeStarts, 
+       int[] exceptionTypeEnds, int bodyStart) {
+       enterAbstractMethod(declarationStart, javaDocPositions, modifiers, modifiersStart, 
+               returnType, returnTypeStart, returnTypeEnd, returnTypeDimensionCount, 
+               name, nameStart, nameEnd, parameterTypes, parameterTypeStarts, 
+               parameterTypeEnds, parameterNames, parameterNameStarts, 
+               parameterNameEnds, parametersEnd, extendedReturnTypeDimensionCount, 
+               extendedReturnTypeDimensionEnd, exceptionTypes, exceptionTypeStarts, 
+               exceptionTypeEnds, bodyStart,false);
+}
+
+protected void enterType(int declarationStart, int[] javaDocPositions, 
+       int modifiers, int modifiersStart, int keywordStart, char[] name, 
+       int nameStart, int nameEnd, char[] superclass, int superclassStart, 
+       int superclassEnd, char[][] superinterfaces, int[] superinterfaceStarts, 
+       int[] superinterfaceEnds, int bodyStart, boolean isClass) {
+       if (fBuildingType) {
+               int[] sourceRange = {declarationStart, -1}; // will be fixed in the exit
+               int[] commentRange = {-1, -1};
+               if (javaDocPositions != null) {
+                       int length = javaDocPositions.length;
+                       commentRange[0] = javaDocPositions[0];
+                       commentRange[1] = javaDocPositions[length - 1];
+               }
+               int[] modifiersRange = {-1, -1};
+               if (modifiersStart > -1) {
+                       modifiersRange[0] = modifiersStart;
+                       modifiersRange[1] = (modifiersStart > -1) ? keywordStart - 1 : -1;
+               }
+               int[] typeKeywordRange = {keywordStart, nameStart - 1};
+               int[] nameRange = new int[] {nameStart, nameEnd};
+               int[] extendsKeywordRange = {-1, -1};
+               int[] superclassRange = {-1, -1};
+               int[] implementsKeywordRange = {-1, -1};
+               int[] interfacesRange = {-1, -1};
+               if (isClass) {
+                       if (superclass != null) {
+                               extendsKeywordRange[0] = nameEnd + 1;
+                               extendsKeywordRange[1] = superclassStart - 1;
+                               superclassRange[0] = superclassStart;
+                               superclassRange[1] = bodyStart - 1;
+                       }
+                       if (superinterfaces != null && superinterfaces.length > 0) {
+                               superclassRange[1] = superclassEnd;
+                               if (superclassEnd > -1) {
+                                       implementsKeywordRange[0] = superclassEnd + 1;
+                               } else {
+                                       implementsKeywordRange[0] = nameEnd + 1;
+                               }
+                               implementsKeywordRange[1] = superinterfaceStarts[0] - 1;
+                               interfacesRange[0] = superinterfaceStarts[0];
+                               interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
+                       }
+               } else {
+                       if (superinterfaces != null && superinterfaces.length > 0) {
+                               extendsKeywordRange[0] = nameEnd + 1;
+                               extendsKeywordRange[1] = superinterfaceStarts[0] - 1;
+                               interfacesRange[0] = superinterfaceStarts[0];
+                               interfacesRange[1] = superinterfaceEnds[superinterfaces.length - 1];
+                       }
+               }
+               int[] openBodyRange = {bodyStart, -1}; // fixed by setTypeRanges(DOMNode)
+               int[] closeBodyRange = {-1, -1}; // will be fixed in exit               
+               fNode = new DOMType(fDocument, sourceRange, new String(name), nameRange, commentRange, 
+                       modifiers, modifiersRange, typeKeywordRange, superclassRange, extendsKeywordRange, 
+                       CharArrayOps.charcharToString(superinterfaces), interfacesRange,
+                       implementsKeywordRange, openBodyRange, 
+                       closeBodyRange, isClass);
+               addChild(fNode);
+               fStack.push(fNode);
+       }
+}
+/**
+ * Finishes the configuration of the constructors and methods.
+ *
+ * @param bodyEnd - a source position corresponding to the closing bracket of the method
+ * @param declarationEnd - a source position corresponding to the end of the method
+ *             declaration.  This can include whitespace and comments following the closing bracket.
+ */
+protected void exitAbstractMethod(int bodyEnd, int declarationEnd) {
+       DOMMethod method = (DOMMethod) fStack.pop();
+       method.setSourceRangeEnd(declarationEnd);
+       method.setBodyRangeEnd(bodyEnd + 1);
+       fNode = method;
+       if (fBuildingSingleMember) {
+               fFinishedSingleMember= true;
+       }
+}
+/**
+ * Finishes the configuration of the class DOM object which
+ * was created by a previous enterClass call.
+ *
+ * @see IDocumentElementRequestor#exitClass(int, int)
+ */
+public void exitClass(int bodyEnd, int declarationEnd) {
+       exitType(bodyEnd, declarationEnd);
+}
+/**
+ * Finishes the configuration of the method DOM object which
+ * was created by a previous enterConstructor call.
+ *
+ * @see IDocumentElementRequestor#exitConstructor(int, int)
+ */
+public void exitConstructor(int bodyEnd, int declarationEnd) {
+       exitAbstractMethod(bodyEnd, declarationEnd);
+}
+/**
+ * Finishes the configuration of the field DOM object which
+ * was created by a previous enterField call.
+ *
+ * @see IDocumentElementRequestor#exitField(int, int)
+ */
+public void exitField(int bodyEnd, int declarationEnd) {
+       DOMField field = (DOMField)fStack.pop();
+       if (field.getEndPosition() < declarationEnd) {
+               field.setSourceRangeEnd(declarationEnd);
+               int nameEnd = field.fNameRange[1];
+               if (nameEnd < bodyEnd) {
+                       /* see 1FVIIV8 - obtain initializer range */
+                       String initializer = new String(fDocument, nameEnd + 1, bodyEnd - nameEnd);
+                       int index = initializer.indexOf('=');
+                       if (index > -1) {
+                               field.setHasInitializer(true);
+                               field.setInitializerRange(nameEnd + index + 2, bodyEnd);
+                       }
+               }
+       }
+       fFieldCount++;
+       fNode = field;
+       if (fBuildingSingleMember) {
+               fFinishedSingleMember= true;
+       }
+}
+/**
+ * Finishes the configuration of the interface DOM object which
+ * was created by a previous enterInterface call.
+ *
+ * @see IDocumentElementRequestor#exitInterface(int, int)
+ */
+public void exitInterface(int bodyEnd, int declarationEnd) {
+       exitType(bodyEnd, declarationEnd);
+}
+/**
+ * Finishes the configuration of the method DOM object which
+ * was created by a previous enterMethod call.
+ *
+ * @see IDocumentElementRequestor#exitMethod(int, int)
+ */
+public void exitMethod(int bodyEnd, int declarationEnd) {
+       exitAbstractMethod(bodyEnd, declarationEnd);
+}
+/**
+ * Creates a new parser.
+ */
+protected DocumentElementParser getParser(Map settings) {
+       return new DocumentElementParser(this, new DefaultProblemFactory());//, new CompilerOptions(settings));
+}
+/**
+ * Initializes the builder to create a document fragment.
+ *
+ * @param sourceCode - the document containing the source code to be analyzed
+ * @param buildingCompilationUnit - true if a the document is being analyzed to
+ *             create a compilation unit, otherwise false
+ * @param buildingType - true if the document is being analyzed to create a
+ *             type or compilation unit
+ * @param singleMember - true if building a single member
+ */
+protected void initializeBuild(char[] sourceCode, boolean buildingCompilationUnit, boolean buildingType, boolean singleMember) {
+       super.initializeBuild(sourceCode, buildingCompilationUnit, buildingType);
+       fBuildingSingleMember= singleMember;
+       fFinishedSingleMember= false;
+
+}
+}