org.eclipse.jdt.internal.formatter.FormatJavadocText Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of vaadin-client-compiler-deps Show documentation
Show all versions of vaadin-client-compiler-deps Show documentation
Vaadin is a web application framework for Rich Internet Applications (RIA).
Vaadin enables easy development and maintenance of fast and
secure rich web
applications with a stunning look and feel and a wide browser support.
It features a server-side architecture with the majority of the logic
running
on the server. Ajax technology is used at the browser-side to ensure a
rich
and interactive user experience.
/*******************************************************************************
* Copyright (c) 2000, 2010 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.jdt.internal.formatter;
import org.eclipse.jdt.internal.formatter.comment.IJavaDocTagConstants;
/**
* Represents text inside a javadoc comment block.
*
* Text may be simple as Line inside a javadoc comment block
* or may be a html tag. Note that to minimize memory footprint, only text
* positions are stored.
*
* Simple text may have one or several lines. When it has several lines, the
* positions of the line breaks are also stored in the {@link #separators} array.
*
* When text has html tags, then they are stored in {@link #htmlNodes} array
* in a recursive way.
*
*/
public class FormatJavadocText extends FormatJavadocNode implements IJavaDocTagConstants {
long[] separators;
int separatorsPtr = -1;
private int htmlTagIndex = -1;
boolean immutable = false;
FormatJavadocNode[] htmlNodes;
int[] htmlIndexes;
int htmlNodesPtr = -1;
int depth = 0;
public FormatJavadocText(int start, int end, int line, int htmlIndex, int htmlDepth) {
super(start, end, line);
this.htmlTagIndex = htmlIndex;
this.depth = htmlDepth;
}
/*
* Append a text to current one.
* If the given text is not an html tag or is a closing tag, then just append to
* the current text recording the separators. Otherwise, create a new html tag
* child node.
*/
void appendText(FormatJavadocText text) {
text.immutable = this.immutable;
if (this.depth == text.depth) {
addSeparator(text);
this.sourceEnd = text.sourceEnd;
if (text.isClosingHtmlTag()) {
// close the tag
this.htmlTagIndex = text.htmlTagIndex;
}
} else {
appendNode(text);
}
if (text.isHtmlTag()) {
switch (text.htmlTagIndex & JAVADOC_TAGS_ID_MASK) {
case JAVADOC_CODE_TAGS_ID:
text.linesBefore = this.htmlNodesPtr == -1 ? 0 : 2;
break;
case JAVADOC_SEPARATOR_TAGS_ID:
text.linesBefore = 1;
break;
case JAVADOC_SINGLE_BREAK_TAG_ID:
if (!text.isClosingHtmlTag()) text.linesBefore = 1;
break;
case JAVADOC_BREAK_TAGS_ID:
if (!text.isClosingHtmlTag()) text.linesBefore = 1;
}
}
}
void appendNode(FormatJavadocNode node) {
if (++this.htmlNodesPtr == 0) { // lazy initialization
this.htmlNodes = new FormatJavadocNode[DEFAULT_ARRAY_SIZE];
} else {
if (this.htmlNodesPtr == this.htmlNodes.length) {
int size = this.htmlNodesPtr + DEFAULT_ARRAY_SIZE;
System.arraycopy(this.htmlNodes, 0, (this.htmlNodes= new FormatJavadocNode[size]), 0, this.htmlNodesPtr);
}
}
addSeparator(node);
this.htmlNodes[this.htmlNodesPtr] = node;
this.sourceEnd = node.sourceEnd;
}
private void addSeparator(FormatJavadocNode node) {
// Just append the text
if (++this.separatorsPtr == 0) { // lazy initialization
this.separators = new long[DEFAULT_ARRAY_SIZE];
this.htmlIndexes = new int[DEFAULT_ARRAY_SIZE];
} else { // resize if needed
if (this.separatorsPtr == this.separators.length) {
int size = this.separatorsPtr + DEFAULT_ARRAY_SIZE;
System.arraycopy(this.separators, 0, (this.separators = new long[size]), 0, this.separatorsPtr);
System.arraycopy(this.htmlIndexes, 0, (this.htmlIndexes = new int[size]), 0, this.separatorsPtr);
}
}
this.separators[this.separatorsPtr] = (((long) this.sourceEnd) << 32) + node.sourceStart;
this.htmlIndexes[this.separatorsPtr] = node.isText() ? ((FormatJavadocText)node).htmlTagIndex : -1;
}
void clean() {
int length = this.separators == null ? 0 : this.separators.length;
if (this.separatorsPtr != (length-1)) {
System.arraycopy(this.separators, 0, this.separators = new long[this.separatorsPtr+1], 0, this.separatorsPtr+1);
System.arraycopy(this.htmlIndexes, 0, this.htmlIndexes = new int[this.separatorsPtr+1], 0, this.separatorsPtr+1);
}
length = this.htmlNodes == null ? 0 : this.htmlNodes.length;
if (this.htmlNodesPtr != (length-1)) {
System.arraycopy(this.htmlNodes, 0, this.htmlNodes = new FormatJavadocNode[this.htmlNodesPtr+1], 0, this.htmlNodesPtr+1);
for (int i=0; i<=this.htmlNodesPtr; i++) {
this.htmlNodes[i].clean();
}
}
}
void closeTag() {
this.htmlTagIndex |= JAVADOC_CLOSED_TAG;
}
int getHtmlTagIndex() {
return this.htmlTagIndex & JAVADOC_TAGS_INDEX_MASK;
}
int getHtmlTagID() {
return this.htmlTagIndex & JAVADOC_TAGS_ID_MASK;
}
FormatJavadocNode getLastNode() {
if (this.htmlNodes != null) {
return this.htmlNodes[this.htmlNodesPtr];
}
return null;
}
/**
* Returns whether the text is a closing html tag or not.
*
* @return true
if the node is an html tag and has '/' before its
* name (e.g. ), false
otherwise.
*/
public boolean isClosingHtmlTag() {
return this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_CLOSED_TAG) != 0;
}
/**
* Returns whether the text is a html tag or not.
*
* @return true
if the node is a html tag, false
* otherwise.
*/
public boolean isHtmlTag() {
return this.htmlTagIndex != -1;
}
/**
* Returns whether the node is an immutable html tag or not.
*
* The text in an immutable tags is never formatted.
*
*
* @return true
if the node is an immutable tag,
* false
otherwise.
*/
public boolean isImmutableHtmlTag() {
return this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID;
}
/**
* Returns whether the text is immutable or not.
*
* A text in considered as immutable when it belongs to an immutable block
* or when it's an immutable html tag.
*
*
* @return true
if the node is an immutable tag,
* false
otherwise.
*/
public boolean isImmutable() {
return this.immutable || (this.htmlTagIndex != -1 && (this.htmlTagIndex & JAVADOC_TAGS_ID_MASK) == JAVADOC_IMMUTABLE_TAGS_ID);
}
/**
* Returns whether the text at the given separator index position is after a
* separator tag or not.
*
* @return true
if the text is after a separator tag,
* false
otherwise or if the given index is out the range of
* the text separators.
*/
public boolean isTextAfterHtmlSeparatorTag(int separatorIndex) {
int ptr = separatorIndex;
if (ptr > this.separatorsPtr) return false;
int tagIndex = this.htmlIndexes[ptr] & JAVADOC_TAGS_ID_MASK;
return tagIndex != -1 && tagIndex == JAVADOC_SEPARATOR_TAGS_ID;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.formatter.FormatJavadocNode#isText()
*/
public boolean isText() {
return true;
}
/* (non-Javadoc)
* @see org.eclipse.jdt.internal.formatter.FormatJavadocNode#setHeaderLine(int)
*/
void setHeaderLine(int javadocLineStart) {
for (int i=0; i 0) {
for (int l=0; l this.separatorsPtr) {
// last node
FormatJavadocNode node = this.htmlNodes[ptr++];
node.toStringDebug(buffer, source);
return;
}
int end = (int) (this.separators[idx] >>> 32);
if (this.htmlNodesPtr >= 0 && ptr <= this.htmlNodesPtr && end > this.htmlNodes[ptr].sourceStart) {
FormatJavadocNode node = this.htmlNodes[ptr++];
node.toStringDebug(buffer, source);
} else {
if (idx > 1 && source[nextStart] != '<') {
buffer.append('\n');
for (int t=0; t