<s> package org . eclipse . jdt . internal . formatter ; import org . eclipse . jdt . internal . compiler . parser . Scanner ; import org . eclipse . jdt . internal . formatter . comment . IJavaDocTagConstants ; public class FormatJavadocBlock extends FormatJavadocNode implements IJavaDocTagConstants { final static int INLINED = 0x0001 ; final static int FIRST = 0x0002 ; final static int ON_HEADER_LINE = 0x0004 ; final static int TEXT_ON_TAG_LINE = 0x0008 ; final static int ONE_LINE_TAG = 0x0010 ; final static int PARAM_TAG = 0x0020 ; final static int IN_PARAM_TAG = 0x0040 ; final static int IN_DESCRIPTION = 0x0080 ; final static int IMMUTABLE = 0x0100 ; final static int MAX_TAG_HIERARCHY = 10 ; private int tagValue = NO_TAG_VALUE ; int tagEnd ; FormatJavadocReference reference ; FormatJavadocNode [ ] nodes ; int nodesPtr = - 1 ; int flags = 0 ; public FormatJavadocBlock ( int start , int end , int line , int value ) { super ( start , end , line ) ; this . tagValue = value ; this . tagEnd = end ; switch ( value ) { case TAG_PARAM_VALUE : case TAG_SERIAL_FIELD_VALUE : case TAG_THROWS_VALUE : case TAG_EXCEPTION_VALUE : this . flags |= PARAM_TAG ; break ; case TAG_CODE_VALUE : case TAG_LITERAL_VALUE : this . flags |= IMMUTABLE ; break ; } } private void addNode ( FormatJavadocNode node ) { if ( ++ this . nodesPtr == 0 ) { this . nodes = new FormatJavadocNode [ DEFAULT_ARRAY_SIZE ] ; } else if ( this . nodesPtr >= this . nodes . length ) { System . arraycopy ( this . nodes , 0 , this . nodes = new FormatJavadocNode [ this . nodes . length + INCREMENT_ARRAY_SIZE ] , 0 , this . nodesPtr ) ; } this . nodes [ this . nodesPtr ] = node ; this . sourceEnd = node . sourceEnd ; } void addBlock ( FormatJavadocBlock block , int htmlLevel ) { if ( this . nodes != null ) { FormatJavadocText [ ] textHierarchy = getTextHierarchy ( block , htmlLevel ) ; if ( textHierarchy != null ) { FormatJavadocText lastText = textHierarchy [ htmlLevel ] ; if ( lastText != null ) { lastText . appendNode ( block ) ; for ( int i = htmlLevel - 1 ; i >= 0 ; i -- ) { textHierarchy [ i ] . sourceEnd = block . sourceEnd ; } this . sourceEnd = block . sourceEnd ; if ( isParamTag ( ) ) { block . flags |= IN_PARAM_TAG ; } else if ( isDescription ( ) ) { block . flags |= IN_DESCRIPTION ; } block . flags |= INLINED ; return ; } } } addNode ( block ) ; if ( isParamTag ( ) ) { block . flags |= IN_PARAM_TAG ; } else if ( isDescription ( ) ) { block . flags |= IN_DESCRIPTION ; } block . flags |= INLINED ; } void addText ( FormatJavadocText text ) { if ( this . nodes != null ) { FormatJavadocText [ ] textHierarchy = getTextHierarchy ( text , text . depth ) ; if ( textHierarchy != null ) { FormatJavadocText lastText = textHierarchy [ text . depth ] ; if ( lastText != null ) { lastText . appendText ( text ) ; for ( int i = text . depth - 1 ; i >= 0 ; i -- ) { textHierarchy [ i ] . sourceEnd = text . sourceEnd ; } this . sourceEnd = text . sourceEnd ; return ; } if ( text . depth > 0 ) { FormatJavadocText parentText = textHierarchy [ text . depth - 1 ] ; if ( parentText != null ) { parentText . appendText ( text ) ; for ( int i = text . depth - 2 ; i >= 0 ; i -- ) { textHierarchy [ i ] . sourceEnd = text . sourceEnd ; } this . sourceEnd = text . sourceEnd ; return ; } } } } if ( text . isHtmlTag ( ) ) { switch ( text . getHtmlTagID ( ) ) { case JAVADOC_CODE_TAGS_ID : text . linesBefore = this . nodesPtr == - 1 ? 0 : 2 ; break ; case JAVADOC_SEPARATOR_TAGS_ID : text . linesBefore = 1 ; break ; } } addNode ( text ) ; if ( isImmutable ( ) ) { text . immutable = true ; } } void clean ( ) { int length = this . nodes == null ? 0 : this . nodes . length ; if ( this . nodesPtr != ( length - 1 ) ) { System . arraycopy ( this . nodes , 0 , this . nodes = new FormatJavadocNode [ this . nodesPtr + 1 ] , 0 , this . nodesPtr + 1 ) ; } for ( int i = 0 ; i <= this . nodesPtr ; i ++ ) { this . nodes [ i ] . clean ( ) ; } } FormatJavadocNode getLastNode ( ) { if ( this . nodes != null ) { return this . nodes [ this . nodesPtr ] ; } return null ; } FormatJavadocText [ ] getTextHierarchy ( FormatJavadocNode node , int htmlDepth ) { if ( this . nodes == null ) return null ; FormatJavadocText [ ] textHierarchy = null ; int ptr = 0 ; FormatJavadocText text = node . isText ( ) ? ( FormatJavadocText ) node : null ; FormatJavadocNode lastNode = this . nodes [ this . nodesPtr ] ; while ( lastNode . isText ( ) ) { FormatJavadocText lastText = ( FormatJavadocText ) lastNode ; int lastTagCategory = lastText . getHtmlTagID ( ) ; boolean lastSingleTag = lastTagCategory <= JAVADOC_SINGLE_TAGS_ID ; boolean lastTextCanHaveChildren = lastText . isHtmlTag ( ) && ! lastText . isClosingHtmlTag ( ) && ! lastSingleTag ; if ( lastText . depth == htmlDepth || lastText . htmlNodesPtr == - 1 ) { if ( lastText . isHtmlTag ( ) ) { boolean setLinesBefore = lastText . separatorsPtr == - 1 || ( ptr == 0 && lastText . isClosingHtmlTag ( ) ) ; if ( ! setLinesBefore && ptr > 0 && lastText . isClosingHtmlTag ( ) ) { FormatJavadocText parentText = textHierarchy [ ptr - 1 ] ; int textStart = ( int ) parentText . separators [ parentText . separatorsPtr ] ; if ( textStart < lastText . sourceStart ) { setLinesBefore = true ; } } if ( setLinesBefore ) { switch ( lastText . getHtmlTagID ( ) ) { case JAVADOC_CODE_TAGS_ID : if ( node . linesBefore < 2 ) { node . linesBefore = 2 ; } break ; case JAVADOC_SEPARATOR_TAGS_ID : case JAVADOC_SINGLE_BREAK_TAG_ID : if ( node . linesBefore < 1 ) { node . linesBefore = 1 ; } } } if ( text != null && text . isHtmlTag ( ) && ! text . isClosingHtmlTag ( ) && text . getHtmlTagIndex ( ) == lastText . getHtmlTagIndex ( ) && ! lastText . isClosingHtmlTag ( ) ) { lastText . closeTag ( ) ; return textHierarchy ; } } if ( lastTextCanHaveChildren || ( htmlDepth == 0 && ! lastText . isHtmlTag ( ) && text != null && ! text . isHtmlTag ( ) ) ) { if ( textHierarchy == null ) textHierarchy = new FormatJavadocText [ htmlDepth + 1 ] ; textHierarchy [ ptr ] = lastText ; return textHierarchy ; } return textHierarchy ; } if ( textHierarchy == null ) textHierarchy = new FormatJavadocText [ htmlDepth + 1 ] ; textHierarchy [ ptr ++ ] = lastText ; lastNode = lastText . htmlNodes [ lastText . htmlNodesPtr ] ; } return textHierarchy ; } public boolean hasTextOnTagLine ( ) { return ( this . flags & TEXT_ON_TAG_LINE ) != 0 ; } public boolean isDescription ( ) { return this . tagValue == NO_TAG_VALUE ; } public boolean isFirst ( ) { return ( this . flags & FIRST ) != 0 ; } public boolean isHeaderLine ( ) { return ( this . flags & ON_HEADER_LINE ) != 0 ; } public boolean isImmutable ( ) { return ( this . flags & IMMUTABLE ) == IMMUTABLE ; } public boolean isInDescription ( ) { return this . tagValue == NO_TAG_VALUE || ( this . flags & IN_DESCRIPTION ) == IN_DESCRIPTION ; } public boolean isInlined ( ) { return ( this . flags & INLINED ) != 0 ; } public boolean isInParamTag ( ) { return ( this . flags & ( PARAM_TAG | IN_PARAM_TAG ) ) != 0 ; } public boolean isOneLineTag ( ) { return ( this . flags & ONE_LINE_TAG ) != 0 ; } public boolean isParamTag ( ) { return ( this . flags & PARAM_TAG ) == PARAM_TAG ; } void setHeaderLine ( int javadocLineStart ) { if ( javadocLineStart == this . lineStart ) { this . flags |= ON_HEADER_LINE ; } for ( int i = 0 ; i < this . nodesPtr ; i ++ ) { this . nodes [ i ] . setHeaderLine ( javadocLineStart ) ; } } protected void toString ( StringBuffer buffer ) { boolean inlined = ( this . flags & INLINED ) != 0 ; if ( inlined ) buffer . append ( "t{" ) ; buffer . append ( '@' ) ; if ( this . tagValue == TAG_OTHERS_VALUE ) { buffer . append ( "others_tag" ) ; } else { buffer . append ( TAG_NAMES [ this . tagValue ] ) ; } super . toString ( buffer ) ; if ( this . reference == null ) { buffer . append ( '\n' ) ; } else { buffer . append ( " (" ) ; this . reference . toString ( buffer ) ; buffer . append ( ")n" ) ; } StringBuffer flagsBuffer = new StringBuffer ( ) ; if ( isDescription ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "description" ) ; } if ( isFirst ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "first" ) ; } if ( isHeaderLine ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "header line" ) ; } if ( isImmutable ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "immutable" ) ; } if ( isInDescription ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "" ) ; } if ( isInlined ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "inlined" ) ; } if ( isInParamTag ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "in param tag" ) ; } if ( isOneLineTag ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "one line tag" ) ; } if ( isParamTag ( ) ) { if ( flagsBuffer . length ( ) > 0 ) flagsBuffer . append ( ',' ) ; flagsBuffer . append ( "param tag" ) ; } if ( flagsBuffer . length ( ) > 0 ) { if ( inlined ) buffer . append ( '\t' ) ; buffer . append ( "tflags: " ) ; buffer . append ( flagsBuffer ) ; buffer . append ( '\n' ) ; } if ( this . nodesPtr > - 1 ) { for ( int i = 0 ; i <= this . nodesPtr ; i ++ ) { if ( inlined ) buffer . append ( '\t' ) ; this . nodes [ i ] . toString ( buffer ) ; } } } public String toStringDebug ( char [ ] source ) { StringBuffer buffer = new StringBuffer ( ) ; toStringDebug ( buffer , source ) ; return buffer . toString ( ) ; } public void toStringDebug ( StringBuffer buffer , char [ ] source ) { if ( this . tagValue > 0 ) { buffer . append ( source , this . sourceStart , this . tagEnd - this . sourceStart + 1 ) ; buffer . append ( ' ' ) ; } if ( this . reference != null ) { this . reference . toStringDebug ( buffer , source ) ; } for ( int i = 0 ; i <= this . nodesPtr ; i ++ ) { this . nodes [ i ] . toStringDebug ( buffer , source ) ; } } void update ( Scanner scanner ) { int blockEnd = scanner . getLineNumber ( this . sourceEnd ) ; if ( blockEnd == this . lineStart ) { this . flags |= FormatJavadocBlock . ONE_LINE_TAG ; } for ( int i = 0 ; i <= this . nodesPtr ; i ++ ) { if ( ! this . nodes [ i ] . isText ( ) ) { ( ( FormatJavadocBlock ) this . nodes [ i ] ) . update ( scanner ) ; } } } } </s>