--- /dev/null
+/*******************************************************************************
+ * 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);
+}
+}