new version with WorkingCopy Management
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / core / jdom / DOMMember.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMember.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/core/jdom/DOMMember.java
new file mode 100644 (file)
index 0000000..19bde2e
--- /dev/null
@@ -0,0 +1,351 @@
+/*******************************************************************************
+ * 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 net.sourceforge.phpdt.core.Flags;
+import net.sourceforge.phpdt.core.jdom.IDOMMember;
+import net.sourceforge.phpdt.internal.compiler.env.IConstants;
+import net.sourceforge.phpdt.internal.core.util.CharArrayBuffer;
+import net.sourceforge.phpdt.internal.core.util.CharArrayOps;
+
+/**
+ * DOMMember provides an implementation of IDOMMember.
+ *
+ * @see IDOMMember
+ * @see DOMNode
+ */
+
+abstract class DOMMember extends DOMNode implements IDOMMember {
+
+       /**
+        * The modifier flags for this member that can be
+        * analyzed with org.eclipse.jdt.core.Flags
+        */
+       protected int    fFlags= 0;
+
+       /**
+        * The member's comments when it has been altered from
+        * the contents in the document, otherwise <code>null</code>.
+        */
+       protected String fComment= null;
+
+       /**
+        * The original inclusive source range of the
+        * member's preceding comments in the document,
+        * or -1's if the member did not originally have a
+        * comment.
+        */
+        protected int[] fCommentRange;
+
+
+       /**
+        * The member's modifiers textual representation when 
+        * the modifiers (flags) have been altered from
+        * their original contents, otherwise <code>null</code>.
+        */
+        protected char[] fModifiers= null;
+
+       /**
+        * The original inclusive source range of the
+        * member's modifiers in the document, or -1's if
+        * the member did not originally have modifiers in
+        * the source code (that is, package default visibility).
+        */
+        protected int[] fModifierRange;
+
+/**
+ * Constructs an empty member node.
+ */
+DOMMember() {
+
+}
+/**
+ * Creates a new member 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.
+ * @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.
+ */
+DOMMember(char[] document, int[] sourceRange, String name, int[] nameRange, int[] commentRange, int flags, int[] modifierRange) {
+       super(document, sourceRange, name, nameRange);
+       fFlags= flags;
+       fComment= null;
+       fCommentRange= commentRange;
+       fModifierRange= modifierRange;
+       setHasComment(commentRange[0] >= 0);
+}
+/**
+ * Appends the contents of this node to the given CharArrayBuffer, using
+ * the original document and indicies as a form for the current attribute values
+ * of this node.
+ *
+ * <p>To facilitate the implementation of generating contents for members,
+ * the content of members is split into three sections - the header,
+ * declaration, and body sections. The header section includes any preceding
+ * comments and modifiers. The declaration section includes the portion of
+ * the member declaration that follows any modifiers and precedes the
+ * member body. The body section includes the member body and any trailing
+ * whitespace.
+ *
+ * @see DOMNode#appendFragmentedContents(CharArrayBuffer)
+ */
+protected void appendFragmentedContents(CharArrayBuffer buffer) {
+       if (isDetailed()) {
+               appendMemberHeaderFragment(buffer);
+               appendMemberDeclarationContents(buffer);
+               appendMemberBodyContents(buffer);
+       } else {
+               appendSimpleContents(buffer);
+       }
+}
+/**
+ * Appends this member's body contents to the given CharArrayBuffer.
+ * Body contents include the member body and any trailing whitespace.
+ */
+protected abstract void appendMemberBodyContents(CharArrayBuffer buffer);
+/**
+ * Appends this member's declaration contents to the given CharArrayBuffer.
+ * The declaration contents includes the portion of this member that
+ * appears after any modifiers and precedes the body.
+ */
+protected abstract void appendMemberDeclarationContents(CharArrayBuffer buffer);
+/**
+ * Appends this member's header contents to the given CharArrayBuffer.
+ * Header contents include any preceding comments and modifiers.
+ */
+protected void appendMemberHeaderFragment(CharArrayBuffer buffer) {
+
+       int spaceStart, spaceEnd;
+
+       // space before comment
+       if (hasComment()) {
+               spaceStart= fSourceRange[0];
+               spaceEnd= fCommentRange[0];
+               if (spaceEnd > 0) {
+                       buffer.append(fDocument, spaceStart, spaceEnd - spaceStart);
+               }
+       }
+       
+       String fragment= getComment();
+       if (fragment != null) {
+               buffer.append(fragment);
+       }
+
+       if (fCommentRange[1] >= 0) {
+               spaceStart= fCommentRange[1] + 1;
+       } else {
+               spaceStart= fSourceRange[0];
+       }
+       if (fModifierRange[0] >= 0) {
+               spaceEnd= fModifierRange[0] - 1;
+       } else {
+               spaceEnd= getMemberDeclarationStartPosition() - 1;
+       }
+
+       if (spaceEnd >= spaceStart) {
+               buffer.append(fDocument, spaceStart, spaceEnd + 1 - spaceStart);
+       }
+       buffer.append(getModifiersText());
+
+}
+/**
+ * Appends the contents of this node to the given CharArrayBuffer, using
+ * the original document and indicies as a form for the current attribute values
+ * of this node. This method is called when this node is know not to have
+ * detailed source indexes.
+ */
+protected abstract void appendSimpleContents(CharArrayBuffer buffer);
+/**
+ * Returns a copy of the given array with the new element appended
+ * to the end of the array.
+ */
+protected String[] appendString(String[] list, String element) {
+       String[] copy= new String[list.length + 1];
+       System.arraycopy(list, 0, copy, 0, list.length);
+       copy[list.length]= element;
+       return copy;
+}
+/**
+ * Returns a <code>String</code> describing the modifiers for this member,
+ * ending with whitespace (if not empty). This value serves as a replacement
+ * value for the member's modifier range when the modifiers have been altered
+ * from their original contents.
+ */
+protected char[] generateFlags() {
+       char[] flags= Flags.toString(getFlags()).toCharArray();
+       if (flags.length == 0) {
+               return flags;
+       } else {
+               return CharArrayOps.concat(flags, new char[] {' '});
+       }
+}
+/**
+ * @see IDOMMember#getComment()
+ */
+public String getComment() {
+       becomeDetailed();
+       if (hasComment()) {
+               if (fComment != null) {
+                       return fComment;
+               } else {
+                       return CharArrayOps.substring(fDocument, fCommentRange[0], fCommentRange[1] + 1 - fCommentRange[0]);
+               }
+       } else {
+               return null;
+       }
+}
+/**
+ * @see IDOMMember#getFlags()
+ */
+public int getFlags() {
+       return fFlags;
+}
+/**
+ * Returns the location of the first character in the member's declaration
+ * section.
+ *
+ * @see DOMMember#getMemberDeclarationContents()
+ * @see DOMMember#getFragmentedContents()
+ */
+protected abstract int getMemberDeclarationStartPosition();
+/**
+ * Returns the String to be used for this member's flags when
+ * generating contents - either the original contents in the document
+ * or the replacement value.
+ */
+protected char[] getModifiersText() {
+       if (fModifiers == null) {
+               if (fModifierRange[0] < 0) {
+                       return null;
+               } else {
+                       return CharArrayOps.subarray(fDocument, fModifierRange[0], fModifierRange[1] + 1 - fModifierRange[0]);
+               }
+       } else {
+               return fModifiers;
+       }
+}
+/**
+ * Returns true if this member currently has a body.
+ */
+protected boolean hasBody() {
+       return getMask(MASK_HAS_BODY);
+}
+/**
+ * Returns true if this member currently has a comment.
+ */
+protected boolean hasComment() {
+       return getMask(MASK_HAS_COMMENT);
+}
+/**
+ * Offsets all the source indexes in this node by the given amount.
+ */
+protected void offset(int offset) {
+       super.offset(offset);
+       offsetRange(fCommentRange, offset);
+       offsetRange(fModifierRange, offset);
+}
+/**
+ * @see IDOMMember#setComment(String)
+ */
+public void setComment(String comment) {
+       becomeDetailed();
+       fComment= comment;
+       fragment();
+       setHasComment(comment != null);
+       /* see 1FVIJAH */
+       if (comment != null) {
+               String commentString = new String(comment);
+               if (commentString.indexOf("@deprecated") >= 0) { //$NON-NLS-1$
+                       fFlags= fFlags | IConstants.AccDeprecated;
+                       return;
+               }
+
+       }
+       fFlags= fFlags & (~IConstants.AccDeprecated);
+
+}
+/**
+ * @see IDOMMember#setFlags(int)
+ */
+public void setFlags(int flags) {
+       becomeDetailed();
+       if (Flags.isDeprecated(fFlags)) {
+               fFlags= flags | IConstants.AccDeprecated;
+       } else {
+               fFlags= flags & (~IConstants.AccDeprecated);
+       }
+       fragment();
+       fModifiers= generateFlags();
+}
+/**
+ * Sets the state of this member declaration as having
+ * a body.
+ */
+protected void setHasBody(boolean hasBody) {
+       setMask(MASK_HAS_BODY, hasBody);
+}
+/**
+ * Sets the state of this member declaration as having
+ * a preceding comment.
+ */
+protected void setHasComment(boolean hasComment) {
+       setMask(MASK_HAS_COMMENT, hasComment);
+}
+/**
+ * Sets the original position of the first character of this node's contents
+ * in its document. This method is only used during DOM creation while
+ * normalizing the source range of each node.
+ *
+ * Synchronize the start of the comment position with the start of the
+ * node.
+ */
+protected void setStartPosition(int start) {
+       if (fCommentRange[0] >= 0) {
+               fCommentRange[0]= start;
+       }
+       super.setStartPosition(start);
+}
+/**
+ * @see DOMNode#shareContents(DOMNode)
+ */
+protected void shareContents(DOMNode node) {
+       super.shareContents(node);
+       DOMMember member= (DOMMember)node;
+       fComment= member.fComment;
+       fCommentRange= rangeCopy(member.fCommentRange);
+       fFlags= member.fFlags;
+       fModifiers= member.fModifiers;
+       fModifierRange= rangeCopy(member.fModifierRange);
+}
+}