new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / jdom / DOMType.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMType.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMType.java
new file mode 100644 (file)
index 0000000..0ec3b3f
--- /dev/null
@@ -0,0 +1,721 @@
+/*******************************************************************************
+ * 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.Enumeration;
+
+import net.sourceforge.phpdt.core.ICompilationUnit;
+import net.sourceforge.phpdt.core.IJavaElement;
+import net.sourceforge.phpdt.core.IType;
+import net.sourceforge.phpdt.core.compiler.ITerminalSymbols;
+import net.sourceforge.phpdt.core.compiler.InvalidInputException;
+import net.sourceforge.phpdt.core.jdom.IDOMMethod;
+import net.sourceforge.phpdt.core.jdom.IDOMNode;
+import net.sourceforge.phpdt.core.jdom.IDOMType;
+import net.sourceforge.phpdt.internal.compiler.parser.Scanner;
+import net.sourceforge.phpdt.internal.compiler.util.Util;
+import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer;
+import net.sourceforge.phpdt.internal.core.util.CharArrayOps;
+
+/**
+ * DOMType provides an implementation of IDOMType.
+ *
+ * @see IDOMType
+ * @see DOMNode
+ */
+/* package */ class DOMType extends DOMMember implements IDOMType {
+
+       /**
+        * The 'class' or 'interface' keyword if altered
+        * from the documents contents, otherwise <code>null</code>.
+        */
+       protected String fTypeKeyword;
+
+       /**
+        * The original inclusive source range of the 'class'
+        * or 'interface' keyword in the document.
+        */
+       protected int[]  fTypeRange;
+
+       /**
+        * The superclass name for the class declaration
+        * if altered from the document's contents, otherwise
+        * <code>null</code>. Also <code>null</code> when this
+        * type represents an interface.
+        */
+       protected String fSuperclass;
+
+       /**
+        * The original inclusive source range of the superclass
+        * name in the document, or -1's of no superclass was
+        * specified in the document.
+        */
+       protected int[]  fSuperclassRange;
+
+
+       /**
+        * The original inclusive souce range of the 'extends' keyword
+        * in the document, including surrounding whitespace, or -1's if
+        * the keyword was not present in the document.
+        */
+       protected int[]  fExtendsRange;
+
+       /**
+        * The original inclusive souce range of the 'implements' keyword
+        * in the document, including surrounding whitespace, or -1's if
+        * the keyword was not present in the document.
+        */     
+       protected int[]  fImplementsRange;
+
+       /**
+        * The comma delimited list of interfaces this type implements
+        * or extends, if altered from the document's contents, otherwise
+        * <code>null</code>. Also <code>null</code> if this type does
+        * not implement or extend any interfaces.
+        */
+       protected char[] fInterfaces;
+
+       /**
+        * The original inclusive source range of the list of interfaces this
+        * type implements or extends, not including any surrouding whitespace.
+        * If the document did not specify interfaces, this array contains -1's.
+        */
+       protected int[]  fInterfacesRange;
+
+       
+
+       /** 
+        * The original source range of the first character following the
+        * type name superclass name, or interface list, up to and including
+        * the first character before the first type member.
+        */     
+       protected int[]  fOpenBodyRange;
+
+       /** 
+        * The original source range of the first new line or non whitespace
+        * character preceding the close brace of the type's body, up to the
+        * and including the first character before the next node (if there are
+        * no following nodes, the range ends at the position of the last
+        * character in the document).
+        */     
+       protected int[]  fCloseBodyRange;
+
+       /**
+        * A list of interfaces this type extends or implements.
+        * <code>null</code> when this type does not extend
+        * or implement any interfaces.
+        */
+       protected String[] fSuperInterfaces= new String[0];
+       
+       /**
+        * This position is the position of the end of the last line separator before the closing brace starting
+        * position of the receiver.
+        */
+//     protected int fInsertionPosition;
+
+/**
+ * Constructs an empty type node.
+ */
+DOMType() {
+
+}
+/**
+ * Creates a new detailed TYPE document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *             entire inclusive source range of this node within its document.
+ *             Contents start on and include the character at the first position.
+ *             Contents end on and include the character at the last position.
+ *             An array of -1's indicates this node's contents do not exist
+ *             in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *             <code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *             entire inclusive source range of this node's name within its document,
+ *             including any array qualifiers that might immediately follow the name
+ *             or -1's if this node does not have a name.
+ * @param commentRange - a two element array describing the comments that precede
+ *             the member declaration. The first matches the start of this node's
+ *             sourceRange, and the second is the new-line or first non-whitespace
+ *             character following the last comment. If no comments are present,
+ *             this array contains two -1's.
+ * @param flags - an integer representing the modifiers for this member. The
+ *             integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param modifierRange - a two element array describing the location of
+ *             modifiers for this member within its source range. The first integer
+ *             is the first character of the first modifier for this member, and
+ *             the second integer is the last whitespace character preceeding the
+ *             next part of this member declaration. If there are no modifiers present
+ *             in this node's source code (that is, package default visibility), this array
+ *             contains two -1's.
+ * @param typeRange - a two element array describing the location of the 'class'
+ *             or 'interface' keyword in the type declaration - first and last character
+ *             positions.
+ * @param superclassRange - a two element array describing the location of the
+ *             superclass name in the type declaration - first and last character
+ *             positions or two -1's if a superclass is not present in the document.
+ * @param extendsRange - a two element array describing the location of the
+ *             'extends' keyword in the type declaration, including any surrounding
+ *             whitespace, or -1's if the 'extends' keyword is not present in the document.
+ * @param implementsList - an array of names of the interfaces this type implements
+ *             or extends, or <code>null</code> if this type does not implement or extend
+ *             any interfaces.
+ * @param implementsRange - a two element array describing the location of the
+ *             comment delimited list of interfaces this type implements or extends,
+ *             not including any surrounding whitespace, or -1's if no interface list
+ *             is present in the document.
+ * @param implementsKeywordRange - a two element array describing the location of the
+ *             'implements' keyword, including any surrounding whitespace, or -1's if no
+ *             'implements' keyword is present in the document.
+ * @param openBodyRange - a two element array describing the location of the
+ *      open brace of the type's body and whitespace following the type declaration
+ *             and preceeding the first member in the type.
+ * @param closeBodyRange - a two element array describing the source range of the
+ *             first new line or non whitespace character preceeding the close brace of the
+ *             type's body, up to the close brace
+ * @param isClass - true is the type is a class, false if it is an interface
+ */
+DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange, int[] typeRange, int[] superclassRange, int[] extendsRange, String[] implementsList, int[] implementsRange, int[] implementsKeywordRange, int[] openBodyRange, int[] closeBodyRange, boolean isClass) {
+       super(document, sourceRange, name, nameRange, commentRange, flags, modifierRange);
+
+       fTypeRange= typeRange;
+       setMask(MASK_TYPE_IS_CLASS, isClass);
+
+       fExtendsRange= extendsRange;
+       fImplementsRange= implementsKeywordRange;
+       fSuperclassRange= superclassRange;
+       fInterfacesRange= implementsRange;
+       fCloseBodyRange= closeBodyRange;
+       setMask(MASK_TYPE_HAS_SUPERCLASS, superclassRange[0] > 0);
+       setMask(MASK_TYPE_HAS_INTERFACES, implementsList != null);
+       fSuperInterfaces= implementsList;
+       fOpenBodyRange= openBodyRange;
+       fCloseBodyRange= closeBodyRange;
+       setMask(MASK_DETAILED_SOURCE_INDEXES, true);
+
+}
+/**
+ * Creates a new simple TYPE document fragment on the given range of the document.
+ *
+ * @param document - the document containing this node's original contents
+ * @param sourceRange - a two element array of integers describing the
+ *             entire inclusive source range of this node within its document.
+ *             Contents start on and include the character at the first position.
+ *             Contents end on and include the character at the last position.
+ *             An array of -1's indicates this node's contents do not exist
+ *             in the document.
+ * @param name - the identifier portion of the name of this node, or
+ *             <code>null</code> if this node does not have a name
+ * @param nameRange - a two element array of integers describing the
+ *             entire inclusive source range of this node's name within its document,
+ *             including any array qualifiers that might immediately follow the name
+ *             or -1's if this node does not have a name.
+ * @param flags - an integer representing the modifiers for this member. The
+ *             integer can be analyzed with org.eclipse.jdt.core.Flags
+ * @param implementsList - an array of names of the interfaces this type implements
+ *             or extends, or <code>null</code> if this type does not implement or extend
+ *             any interfaces.
+ * @param isClass - true is the type is a class, false if it is an interface
+ */
+DOMType(char[] document, int[] sourceRange, String name, int[] nameRange, int flags, String[] implementsList, boolean isClass) {
+       this(document, sourceRange, name, nameRange, new int[] {-1, -1}, flags,
+               new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1},
+               implementsList, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {-1, -1}, new int[] {sourceRange[1], sourceRange[1]}, isClass);
+       setMask(MASK_DETAILED_SOURCE_INDEXES, false);
+}
+/**
+ * @see IDOMType#addSuperInterface(String)
+ */
+public void addSuperInterface(String name) throws IllegalArgumentException {
+       if (name == null) {
+               throw new IllegalArgumentException(Util.bind("dom.addNullInterface")); //$NON-NLS-1$
+       }
+       if (fSuperInterfaces == null) {
+               fSuperInterfaces= new String[1];
+               fSuperInterfaces[0]= name;
+       } else {
+               fSuperInterfaces= appendString(fSuperInterfaces, name);
+       }
+       setSuperInterfaces(fSuperInterfaces);
+}
+/**
+ * @see DOMMember#appendMemberBodyContents(CharArrayBuffer)
+ */
+protected void appendMemberBodyContents(CharArrayBuffer buffer) {
+       buffer.append(fDocument, fOpenBodyRange[0], fOpenBodyRange[1] + 1 - fOpenBodyRange[0]);
+       appendContentsOfChildren(buffer);
+       buffer.append(fDocument, fCloseBodyRange[0], fCloseBodyRange[1] + 1 - fCloseBodyRange[0]);
+       buffer.append(fDocument, fCloseBodyRange[1] + 1, fSourceRange[1] - fCloseBodyRange[1]);
+}
+/**
+ * @see DOMMember#appendMemberDeclarationContents(CharArrayBuffer )
+ */
+protected void appendMemberDeclarationContents(CharArrayBuffer  buffer) {
+       
+       if (fTypeKeyword != null) {
+               buffer.append(fTypeKeyword);
+               buffer.append(fDocument, fTypeRange[1], fNameRange[0] - fTypeRange[1] );
+       } else {
+               buffer.append(fDocument, fTypeRange[0], fTypeRange[1] + 1 - fTypeRange[0]);
+       }
+
+       buffer.append(getName());
+
+       if (isClass()) {
+               boolean hasSuperclass = false, hasInterfaces = false;
+               if (getMask(MASK_TYPE_HAS_SUPERCLASS)) {
+                       hasSuperclass = true;
+                       if (fExtendsRange[0] < 0) {
+                               buffer.append(" extends "); //$NON-NLS-1$
+                       } else {
+                               buffer.append(fDocument, fExtendsRange[0], fExtendsRange[1] + 1 - fExtendsRange[0]);
+                       }
+                       if (fSuperclass != null) {
+                               buffer.append(fSuperclass);
+                       } else {
+                               buffer.append(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]);
+                       }
+               }
+               if (getMask(MASK_TYPE_HAS_INTERFACES)) {
+                       hasInterfaces = true;
+                       if (fImplementsRange[0] < 0) {
+                               buffer.append(" implements "); //$NON-NLS-1$
+                       } else {
+                               buffer.append(fDocument, fImplementsRange[0], fImplementsRange[1] + 1 - fImplementsRange[0]);
+                       }
+                       if (fInterfaces != null) {
+                               buffer.append(fInterfaces);
+                       } else {
+                               buffer.append(fDocument, fInterfacesRange[0], fInterfacesRange[1] + 1 - fInterfacesRange[0]);
+                       }
+               }
+               if (hasInterfaces) {
+                       if (fImplementsRange[0] < 0) {
+                               buffer.append(' ');
+                       } else {
+                               buffer.append(fDocument, fInterfacesRange[1] + 1, fOpenBodyRange[0] - fInterfacesRange[1] - 1);
+                       }
+               } else {
+                       if (hasSuperclass) {
+                               if (fSuperclassRange[0] < 0) {
+                                       buffer.append(' ');
+                               } else {
+                                       buffer.append(fDocument, fSuperclassRange[1] + 1, fOpenBodyRange[0] - fSuperclassRange[1] - 1);
+                               }
+                       } else {
+                               buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] - fNameRange[1] - 1);
+                       }
+               }
+       } else {
+               if (getMask(MASK_TYPE_HAS_INTERFACES)) {
+                       if (fExtendsRange[0] < 0) {
+                               buffer.append(" extends "); //$NON-NLS-1$
+                       } else {
+                               buffer.append(fDocument, fExtendsRange[0], fExtendsRange[1] + 1 - fExtendsRange[0]);
+                       }
+                       if (fInterfaces != null) {
+                               buffer.append(fInterfaces);
+                               buffer.append(' ');
+                       } else {
+                               buffer.append(fDocument, fInterfacesRange[0], fInterfacesRange[1] + 1 - fInterfacesRange[0]);
+                       }
+               } else {
+                       buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[0] - fNameRange[1] - 1);
+               }
+       }
+       
+}
+/**
+ * @see DOMNode#appendSimpleContents(CharArrayBuffer)
+ */
+protected void appendSimpleContents(CharArrayBuffer buffer) {
+       // append eveything before my name
+       buffer.append(fDocument, fSourceRange[0], fNameRange[0] - fSourceRange[0]);
+       // append my name
+       buffer.append(fName);
+
+       
+       // append everything after my name and before my first child
+       buffer.append(fDocument, fNameRange[1] + 1, fOpenBodyRange[1] - fNameRange[1]);
+       // append my children
+       appendContentsOfChildren(buffer);
+       // append from my last child to my end
+       buffer.append(fDocument, fCloseBodyRange[0], fSourceRange[1] - fCloseBodyRange[0] + 1);
+
+
+}
+/**
+ * @see IDOMNode#canHaveChildren()
+ */
+public boolean canHaveChildren() {
+       return true;
+}
+/**
+ * Returns the position of the closing brace for the body of this type.
+ * This value this method returns is only valid before the type has
+ * been normalized and is present only for normalization.
+ */
+int getCloseBodyPosition() {
+       return fCloseBodyRange[0];
+}
+/**
+ * @see DOMNode#getDetailedNode()
+ */
+//protected DOMNode getDetailedNode() {
+//     return (DOMNode)getFactory().createType(getContents());
+//}
+/**
+ * @see DOMNode#getInsertionPosition()
+ */
+public int getInsertionPosition() {
+       // this should return the position of the end of the last line separator before the closing brace of the type
+       // See PR 1GELSDQ: ITPJUI:WINNT - JDOM: IType.createMethod does not insert nicely for inner types
+       return fInsertionPosition;
+}
+/**
+ * @see IDOMNode#getJavaElement
+ */
+public IJavaElement getJavaElement(IJavaElement parent) throws IllegalArgumentException {
+       if (parent.getElementType() == IJavaElement.TYPE) {
+               return ((IType)parent).getType(getName());
+       } else if (parent.getElementType() == IJavaElement.COMPILATION_UNIT) {
+               return ((ICompilationUnit)parent).getType(getName());
+       } else {
+               throw new IllegalArgumentException(Util.bind("element.illegalParent")); //$NON-NLS-1$
+       }
+}
+/**
+ * @see DOMMember#getMemberDeclarationStartPosition()
+ */
+protected int getMemberDeclarationStartPosition() {
+       return fTypeRange[0];
+}
+/**
+ * @see IDOMNode#getNodeType()
+ */
+public int getNodeType() {
+       return IDOMNode.TYPE;
+}
+/**
+ * Answers the open body range end position.
+ */
+int getOpenBodyEnd() {
+       return fOpenBodyRange[1];
+}
+/**
+ * @see IDOMType#getSuperclass()
+ */
+public String getSuperclass() {
+       becomeDetailed();
+       if (getMask(MASK_TYPE_HAS_SUPERCLASS)) {
+               if (fSuperclass != null) {
+                       return fSuperclass;
+               } else {
+                       return CharArrayOps.substring(fDocument, fSuperclassRange[0], fSuperclassRange[1] + 1 - fSuperclassRange[0]);
+               }
+       } else {
+               return null;
+       }
+}
+/**
+ * @see IDOMType#getSuperInterfaces()
+ */
+public String[] getSuperInterfaces() {
+       return fSuperInterfaces;
+}
+/**
+ * @see IDOMNode
+ */
+public boolean isAllowableChild(IDOMNode node) {
+       if (node != null) {
+               int type= node.getNodeType();
+               return type == IDOMNode.TYPE || type == IDOMNode.FIELD|| type == IDOMNode.METHOD || 
+                       type == IDOMNode.INITIALIZER; 
+       } else {
+               return false;
+       }
+       
+}
+/**
+ * @see IDOMType#isClass()
+ */
+public boolean isClass() {
+       return getMask(MASK_TYPE_IS_CLASS);
+}
+/**
+ * @see DOMNode
+ */
+protected DOMNode newDOMNode() {
+       return new DOMType();
+}
+/**
+ * Normalizes this <code>DOMNode</code>'s source positions to include whitespace preceeding
+ * the node on the line on which the node starts, and all whitespace after the node up to
+ * the next node's start
+ */
+void normalize(ILineStartFinder finder) {
+       // perform final changes to the open and close body ranges
+       int openBodyEnd, openBodyStart, closeBodyStart, closeBodyEnd;
+       DOMNode first = (DOMNode) getFirstChild();
+       DOMNode lastNode = null;
+       // look for the open body
+       Scanner scanner = new Scanner();
+       scanner.setSource(fDocument);
+       scanner.resetTo(fNameRange[1] + 1, fDocument.length);
+       
+       try {
+               int currentToken = scanner.getNextToken();
+               while(currentToken != ITerminalSymbols.TokenNameLBRACE &&
+                               currentToken != ITerminalSymbols.TokenNameEOF) {
+                       currentToken = scanner.getNextToken();
+               }
+               if(currentToken == ITerminalSymbols.TokenNameLBRACE) {          
+                       openBodyEnd = scanner.currentPosition - 1;
+                       openBodyStart = scanner.startPosition;
+               } else {
+                       openBodyEnd = fDocument.length;
+                       openBodyStart = fDocument.length;
+               }
+       } catch(InvalidInputException e) {
+               openBodyEnd = fDocument.length;
+               openBodyStart = fDocument.length;
+       }
+       if (first != null) {
+               int lineStart = finder.getLineStart(first.getStartPosition());
+               if (lineStart > openBodyEnd) {
+                       openBodyEnd = lineStart - 1;
+               } else {
+                       openBodyEnd = first.getStartPosition() - 1;
+               }               
+               lastNode = (DOMNode) first.getNextNode();
+               if (lastNode == null) {
+                       lastNode = first;
+               } else {
+                       while (lastNode.getNextNode() != null) {
+                               lastNode = (DOMNode) lastNode.getNextNode();
+                       }
+               }
+               scanner.setSource(fDocument);
+               scanner.resetTo(lastNode.getEndPosition() + 1, fDocument.length);
+               try {
+                       int currentToken = scanner.getNextToken();
+                       while(currentToken != ITerminalSymbols.TokenNameRBRACE &&
+                                       currentToken != ITerminalSymbols.TokenNameEOF) {
+                               currentToken = scanner.getNextToken();
+                       }
+                       if(currentToken == ITerminalSymbols.TokenNameRBRACE) {          
+                               closeBodyStart = scanner.startPosition;
+                               closeBodyEnd = scanner.currentPosition - 1;
+                       } else {
+                               closeBodyStart = fDocument.length;
+                               closeBodyEnd = fDocument.length;
+                       }
+               } catch(InvalidInputException e) {
+                       closeBodyStart = fDocument.length;
+                       closeBodyEnd = fDocument.length;
+               }
+       } else {
+               scanner.resetTo(openBodyEnd, fDocument.length);
+               try {
+                       int currentToken = scanner.getNextToken();
+                       while(currentToken != ITerminalSymbols.TokenNameRBRACE &&
+                                       currentToken != ITerminalSymbols.TokenNameEOF) {
+                               currentToken = scanner.getNextToken();
+                       }
+                       if(currentToken == ITerminalSymbols.TokenNameRBRACE) {          
+                               closeBodyStart = scanner.startPosition;
+                               closeBodyEnd = scanner.currentPosition - 1;
+                       } else {
+                               closeBodyStart = fDocument.length;
+                               closeBodyEnd = fDocument.length;
+                       }
+               } catch(InvalidInputException e) {
+                       closeBodyStart = fDocument.length;
+                       closeBodyEnd = fDocument.length;
+               }
+               openBodyEnd = closeBodyEnd - 1;
+       }
+       setOpenBodyRangeEnd(openBodyEnd);
+       setOpenBodyRangeStart(openBodyStart);
+       setCloseBodyRangeStart(closeBodyStart);
+       setCloseBodyRangeEnd(closeBodyEnd);
+       fInsertionPosition = finder.getLineStart(closeBodyStart);
+       if (lastNode != null && fInsertionPosition < lastNode.getEndPosition()) {
+               fInsertionPosition = getCloseBodyPosition();
+       }
+       if (fInsertionPosition <= openBodyEnd) {
+               fInsertionPosition = getCloseBodyPosition();
+       }
+       super.normalize(finder);
+}
+
+/**
+ * Normalizes this <code>DOMNode</code>'s end position.
+ */
+void normalizeEndPosition(ILineStartFinder finder, DOMNode next) {
+       if (next == null) {
+               // this node's end position includes all of the characters up
+               // to the end of the enclosing node
+               DOMNode parent = (DOMNode) getParent();
+               if (parent == null || parent instanceof DOMCompilationUnit) {
+                       setSourceRangeEnd(fDocument.length - 1);
+               } else {
+                       // parent is a type
+                       setSourceRangeEnd(((DOMType)parent).getCloseBodyPosition() - 1);
+               }
+       } else {
+               // this node's end position is just before the start of the next node
+               next.normalizeStartPosition(getEndPosition(), finder);
+               setSourceRangeEnd(next.getStartPosition() - 1);
+       }
+}
+
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+       super.offset(offset);
+       offsetRange(fCloseBodyRange, offset);
+       offsetRange(fExtendsRange, offset);
+       offsetRange(fImplementsRange, offset);
+       offsetRange(fInterfacesRange, offset);
+       offsetRange(fOpenBodyRange, offset);
+       offsetRange(fSuperclassRange, offset);
+       offsetRange(fTypeRange, offset);
+}
+/**
+ * @see IDOMType#setClass(boolean)
+ */
+public void setClass(boolean b) {
+       becomeDetailed();
+       fragment();
+       setMask(MASK_TYPE_IS_CLASS, b);
+       if (b) {
+               fTypeKeyword= "class"; //$NON-NLS-1$
+       } else {
+               fTypeKeyword= "interface"; //$NON-NLS-1$
+               setSuperclass(null);
+       }
+}
+/**
+ * Sets the end of the close body range 
+ */
+void setCloseBodyRangeEnd(int end) {
+       fCloseBodyRange[1] = end;
+}
+/**
+ * Sets the start of the close body range 
+ */
+void setCloseBodyRangeStart(int start) {
+       fCloseBodyRange[0] = start;
+}
+/**
+ * Sets the name of this node.
+ *
+ * <p>When the name of a type is set, all of its constructors must be marked
+ * as fragmented, since the names of the constructors must reflect the name
+ * of this type.
+ *
+ * @see IDOMNode#setName(char[])
+ */
+public void setName(String name) throws IllegalArgumentException {
+       if (name == null) {
+               throw new IllegalArgumentException(Util.bind("element.nullName")); //$NON-NLS-1$
+       }
+       super.setName(name);
+       Enumeration children= getChildren();
+       while (children.hasMoreElements()) {
+               IDOMNode child= (IDOMNode)children.nextElement();
+               if (child.getNodeType() == IDOMNode.METHOD && ((IDOMMethod)child).isConstructor()) {
+                       ((DOMNode)child).fragment();
+               }
+       }
+}
+/**
+ * Sets the end of the open body range 
+ */
+void setOpenBodyRangeEnd(int end) {
+       fOpenBodyRange[1] = end;
+}
+/**
+ * Sets the start of the open body range 
+ */
+void setOpenBodyRangeStart(int start) {
+       fOpenBodyRange[0] = start;
+}
+/**
+ * @see IDOMType#setSuperclass(char[])
+ */
+public void setSuperclass(String superclassName) {
+       becomeDetailed();
+       fragment();
+       fSuperclass= superclassName;
+       setMask(MASK_TYPE_HAS_SUPERCLASS, superclassName != null);
+}
+/**
+ * @see IDOMType#setSuperInterfaces(String[])
+ */
+public void setSuperInterfaces(String[] names) {
+       becomeDetailed();
+       if (names == null) {
+               throw new IllegalArgumentException(Util.bind("dom.nullInterfaces")); //$NON-NLS-1$
+       }
+       fragment();
+       fSuperInterfaces= names;
+       if (names == null || names.length == 0) {
+               fInterfaces= null;
+               fSuperInterfaces= null;
+               setMask(MASK_TYPE_HAS_INTERFACES, false);
+       } else {
+               setMask(MASK_TYPE_HAS_INTERFACES, true);
+               CharArrayBuffer buffer = new CharArrayBuffer();
+               for (int i = 0; i < names.length; i++) {
+                       if (i > 0) {
+                               buffer.append(", "); //$NON-NLS-1$
+                       }
+                       buffer.append(names[i]);
+               }
+               fInterfaces = buffer.getContents();
+       }
+}
+/**
+ * Sets the type keyword
+ */
+void setTypeKeyword(String keyword) {
+       fTypeKeyword = keyword;
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+       super.shareContents(node);
+       DOMType type= (DOMType)node;
+       fCloseBodyRange= rangeCopy(type.fCloseBodyRange);
+       fExtendsRange= type.fExtendsRange;
+       fImplementsRange= rangeCopy(type.fImplementsRange);
+       fInterfaces= type.fInterfaces;
+       fInterfacesRange= rangeCopy(type.fInterfacesRange);
+       fOpenBodyRange= rangeCopy(type.fOpenBodyRange);
+       fSuperclass= type.fSuperclass;
+       fSuperclassRange= rangeCopy(type.fSuperclassRange);
+       fSuperInterfaces= type.fSuperInterfaces;
+       fTypeKeyword= type.fTypeKeyword;
+       fTypeRange= rangeCopy(type.fTypeRange);
+}
+/**
+ * @see IDOMNode#toString()
+ */
+public String toString() {
+       return "TYPE: " + getName(); //$NON-NLS-1$
+}
+}