<s> package org . eclipse . jdt . internal . formatter ; import java . util . List ; import org . eclipse . jdt . core . compiler . CharOperation ; import org . eclipse . jdt . core . compiler . InvalidInputException ; import org . eclipse . jdt . internal . compiler . classfmt . ClassFileConstants ; import org . eclipse . jdt . internal . compiler . parser . JavadocParser ; import org . eclipse . jdt . internal . compiler . parser . ScannerHelper ; import org . eclipse . jdt . internal . compiler . parser . TerminalTokens ; import org . eclipse . jdt . internal . formatter . comment . IJavaDocTagConstants ; public class FormatterCommentParser extends JavadocParser implements IJavaDocTagConstants { char [ ] [ ] htmlTags ; int htmlTagsPtr = - 1 ; int inlineHtmlTagsPtr = - 1 ; private boolean invalidTagName ; public boolean parseHtmlTags ; public FormatterCommentParser ( long sourceLevel ) { super ( null ) ; this . kind = FORMATTER_COMMENT_PARSER | TEXT_PARSE ; this . reportProblems = false ; this . checkDocComment = true ; this . sourceLevel = sourceLevel ; } public boolean parse ( int start , int end ) { this . javadocStart = start ; this . javadocEnd = end ; this . firstTagPosition = this . javadocStart ; this . htmlTagsPtr = - 1 ; boolean valid = commentParse ( ) ; return valid && this . docComment != null ; } protected Object createArgumentReference ( char [ ] name , int dim , boolean isVarargs , Object ref , long [ ] dimPositions , long argNamePos ) throws InvalidInputException { FormatJavadocReference typeRef = ( FormatJavadocReference ) ref ; if ( dim > 0 ) { typeRef . sourceEnd = ( int ) dimPositions [ dim - 1 ] ; } if ( argNamePos >= 0 ) typeRef . sourceEnd = ( int ) argNamePos ; return ref ; } protected boolean createFakeReference ( int start ) { this . scanner . currentPosition = this . index ; int lineStart = this . scanner . getLineNumber ( start ) ; FormatJavadocReference reference = new FormatJavadocReference ( start , this . index - 1 , lineStart ) ; return pushSeeRef ( reference ) ; } protected Object createFieldReference ( Object receiver ) throws InvalidInputException { int start = receiver == null ? this . memberStart : ( ( FormatJavadocReference ) receiver ) . sourceStart ; int lineStart = this . scanner . getLineNumber ( start ) ; return new FormatJavadocReference ( start , ( int ) this . identifierPositionStack [ 0 ] , lineStart ) ; } protected Object createMethodReference ( Object receiver , List arguments ) throws InvalidInputException { int start = receiver == null ? this . memberStart : ( ( FormatJavadocReference ) receiver ) . sourceStart ; int lineStart = this . scanner . getLineNumber ( start ) ; return new FormatJavadocReference ( start , this . scanner . getCurrentTokenEndPosition ( ) , lineStart ) ; } protected void createTag ( ) { int lineStart = this . scanner . getLineNumber ( this . tagSourceStart ) ; if ( this . inlineTagStarted ) { FormatJavadocBlock block = new FormatJavadocBlock ( this . inlineTagStart , this . tagSourceEnd , lineStart , this . tagValue ) ; FormatJavadocBlock previousBlock = null ; if ( this . astPtr == - 1 ) { previousBlock = new FormatJavadocBlock ( this . inlineTagStart , this . tagSourceEnd , lineStart , NO_TAG_VALUE ) ; pushOnAstStack ( previousBlock , true ) ; } else { previousBlock = ( FormatJavadocBlock ) this . astStack [ this . astPtr ] ; } previousBlock . addBlock ( block , this . htmlTagsPtr == - 1 ? 0 : this . htmlTagsPtr ) ; } else { FormatJavadocBlock block = new FormatJavadocBlock ( this . tagSourceStart , this . tagSourceEnd , lineStart , this . tagValue ) ; pushOnAstStack ( block , true ) ; } } protected Object createTypeReference ( int primitiveToken ) { int size = this . identifierLengthStack [ this . identifierLengthPtr ] ; if ( size == 0 ) return null ; int start = ( int ) ( this . identifierPositionStack [ this . identifierPtr ] >>> 32 ) ; int lineStart = this . scanner . getLineNumber ( start ) ; if ( size == 1 ) { return new FormatJavadocReference ( this . identifierPositionStack [ this . identifierPtr ] , lineStart ) ; } long [ ] positions = new long [ size ] ; System . arraycopy ( this . identifierPositionStack , this . identifierPtr - size + 1 , positions , 0 , size ) ; return new FormatJavadocReference ( ( int ) ( positions [ 0 ] >>> 32 ) , ( int ) positions [ positions . length - 1 ] , lineStart ) ; } private int getHtmlTagIndex ( char [ ] htmlTag ) { int length = htmlTag == null ? 0 : htmlTag . length ; int tagId = 0 ; if ( length > 0 ) { for ( int i = 0 , max = JAVADOC_SINGLE_BREAK_TAG . length ; i < max ; i ++ ) { char [ ] tag = JAVADOC_SINGLE_BREAK_TAG [ i ] ; if ( length == tag . length && CharOperation . equals ( htmlTag , tag , false ) ) { return ( tagId | JAVADOC_SINGLE_BREAK_TAG_ID ) + i ; } } for ( int i = 0 , max = JAVADOC_CODE_TAGS . length ; i < max ; i ++ ) { char [ ] tag = JAVADOC_CODE_TAGS [ i ] ; if ( length == tag . length && CharOperation . equals ( htmlTag , tag , false ) ) { return ( tagId | JAVADOC_CODE_TAGS_ID ) + i ; } } for ( int i = 0 , max = JAVADOC_BREAK_TAGS . length ; i < max ; i ++ ) { char [ ] tag = JAVADOC_BREAK_TAGS [ i ] ; if ( length == tag . length && CharOperation . equals ( htmlTag , tag , false ) ) { return ( tagId | JAVADOC_BREAK_TAGS_ID ) + i ; } } for ( int i = 0 , max = JAVADOC_IMMUTABLE_TAGS . length ; i < max ; i ++ ) { char [ ] tag = JAVADOC_IMMUTABLE_TAGS [ i ] ; if ( length == tag . length && CharOperation . equals ( htmlTag , tag , false ) ) { return ( tagId | JAVADOC_IMMUTABLE_TAGS_ID ) + i ; } } for ( int i = 0 , max = JAVADOC_SEPARATOR_TAGS . length ; i < max ; i ++ ) { char [ ] tag = JAVADOC_SEPARATOR_TAGS [ i ] ; if ( length == tag . length && CharOperation . equals ( htmlTag , tag , false ) ) { return ( tagId | JAVADOC_SEPARATOR_TAGS_ID ) + i ; } } } return JAVADOC_TAGS_ID_MASK ; } protected boolean parseHtmlTag ( int previousPosition , int endTextPosition ) throws InvalidInputException { if ( ! this . parseHtmlTags ) return false ; boolean closing = false ; boolean valid = false ; boolean incremented = false ; int start = this . scanner . currentPosition ; int currentPosition = start ; int htmlPtr = this . htmlTagsPtr ; char firstChar = peekChar ( ) ; boolean hasWhitespaces = firstChar == ' ' || ScannerHelper . isWhitespace ( firstChar ) ; try { int token = readTokenAndConsume ( ) ; char [ ] htmlTag ; int htmlIndex ; switch ( token ) { case TerminalTokens . TokenNameIdentifier : htmlTag = this . scanner . getCurrentIdentifierSource ( ) ; htmlIndex = getHtmlTagIndex ( htmlTag ) ; if ( htmlIndex == JAVADOC_TAGS_ID_MASK ) return false ; if ( htmlPtr >= 0 ) { int lastHtmlTagIndex = getHtmlTagIndex ( this . htmlTags [ htmlPtr ] ) ; if ( ( lastHtmlTagIndex & JAVADOC_TAGS_ID_MASK ) == JAVADOC_IMMUTABLE_TAGS_ID ) { if ( ( htmlIndex & JAVADOC_TAGS_ID_MASK ) == JAVADOC_CODE_TAGS_ID ) { FormatJavadocBlock previousBlock = ( FormatJavadocBlock ) this . astStack [ this . astPtr ] ; FormatJavadocNode parentNode = previousBlock ; FormatJavadocNode lastNode = parentNode ; while ( lastNode . getLastNode ( ) != null ) { parentNode = lastNode ; lastNode = lastNode . getLastNode ( ) ; } if ( lastNode . isText ( ) ) { FormatJavadocText text = ( FormatJavadocText ) lastNode ; if ( text . separatorsPtr == - 1 ) { break ; } } } return false ; } } if ( ( htmlIndex & JAVADOC_TAGS_ID_MASK ) > JAVADOC_SINGLE_TAGS_ID ) { if ( this . htmlTagsPtr == - 1 || ! CharOperation . equals ( this . htmlTags [ this . htmlTagsPtr ] , htmlTag , false ) ) { if ( ++ this . htmlTagsPtr == 0 ) { this . htmlTags = new char [ AST_STACK_INCREMENT ] [ ] ; } else { if ( this . htmlTagsPtr == this . htmlTags . length ) { System . arraycopy ( this . htmlTags , 0 , ( this . htmlTags = new char [ this . htmlTags . length + AST_STACK_INCREMENT ] [ ] ) , 0 , this . htmlTagsPtr ) ; } } this . htmlTags [ this . htmlTagsPtr ] = htmlTag ; incremented = true ; } } currentPosition = this . scanner . currentPosition ; if ( readToken ( ) == TerminalTokens . TokenNameDIVIDE ) { consumeToken ( ) ; } break ; case TerminalTokens . TokenNameDIVIDE : if ( this . htmlTagsPtr == - 1 ) return false ; htmlTag = this . htmlTags [ this . htmlTagsPtr ] ; if ( ( token = readTokenAndConsume ( ) ) != TerminalTokens . TokenNameIdentifier ) { return false ; } char [ ] identifier = this . scanner . getCurrentIdentifierSource ( ) ; htmlIndex = getHtmlTagIndex ( identifier ) ; if ( htmlIndex == JAVADOC_TAGS_ID_MASK ) return false ; int ptr = this . htmlTagsPtr ; while ( ! CharOperation . equals ( htmlTag , identifier , false ) ) { if ( this . htmlTagsPtr <= 0 ) { this . htmlTagsPtr = ptr ; return false ; } this . htmlTagsPtr -- ; htmlTag = this . htmlTags [ this . htmlTagsPtr ] ; } htmlIndex |= JAVADOC_CLOSED_TAG ; closing = true ; currentPosition = this . scanner . currentPosition ; break ; default : return false ; } switch ( readTokenAndConsume ( ) ) { case TerminalTokens . TokenNameLESS : case TerminalTokens . TokenNameLESS_EQUAL : return false ; case TerminalTokens . TokenNameGREATER : break ; case TerminalTokens . TokenNameGREATER_EQUAL : case TerminalTokens . TokenNameRIGHT_SHIFT : case TerminalTokens . TokenNameRIGHT_SHIFT_EQUAL : break ; default : this . index = currentPosition ; loop : while ( true ) { switch ( readChar ( ) ) { case '<' : if ( hasWhitespaces ) { return false ; } this . index = currentPosition ; this . scanner . startPosition = currentPosition ; this . scanner . currentPosition = currentPosition ; this . scanner . currentCharacter = '<' ; break loop ; case '>' : this . scanner . startPosition = this . index ; this . scanner . currentPosition = this . index ; this . scanner . currentCharacter = peekChar ( ) ; break loop ; default : break ; } if ( this . index >= this . javadocTextEnd ) { this . index = currentPosition ; this . scanner . startPosition = currentPosition ; this . scanner . currentPosition = currentPosition ; break ; } } } if ( this . lineStarted && this . textStart != - 1 && this . textStart < endTextPosition ) { pushText ( this . textStart , endTextPosition , - 1 , htmlPtr ) ; } pushText ( previousPosition , this . index , htmlIndex , this . htmlTagsPtr ) ; this . textStart = - 1 ; valid = true ; } finally { if ( valid ) { if ( closing ) { this . htmlTagsPtr -- ; } } else if ( ! this . abort ) { if ( incremented ) { this . htmlTagsPtr -- ; if ( this . htmlTagsPtr == - 1 ) this . htmlTags = null ; } this . scanner . resetTo ( start , this . scanner . eofPosition - 1 ) ; this . index = start ; } } return valid ; } protected boolean parseIdentifierTag ( boolean report ) { if ( super . parseIdentifierTag ( report ) ) { createTag ( ) ; this . index = this . tagSourceEnd + 1 ; this . scanner . resetTo ( this . index , this . javadocEnd ) ; return true ; } this . tagValue = TAG_OTHERS_VALUE ; return false ; } protected boolean parseParam ( ) throws InvalidInputException { boolean valid = super . parseParam ( ) ; if ( ! valid ) { this . scanner . resetTo ( this . tagSourceEnd + 1 , this . javadocEnd ) ; this . index = this . tagSourceEnd + 1 ; char ch = peekChar ( ) ; if ( ch == ' ' || ScannerHelper . isWhitespace ( ch ) ) { int token = this . scanner . getNextToken ( ) ; if ( token == TerminalTokens . TokenNameIdentifier ) { ch = peekChar ( ) ; if ( ch == ' ' || ScannerHelper . isWhitespace ( ch ) ) { pushIdentifier ( true , false ) ; pushParamName ( false ) ; this . index = this . scanner . currentPosition ; valid = true ; } } this . scanner . resetTo ( this . tagSourceEnd + 1 , this . javadocEnd ) ; } this . tagValue = TAG_OTHERS_VALUE ; } return valid ; } protected boolean parseReference ( ) throws InvalidInputException { boolean valid = super . parseReference ( ) ; if ( ! valid ) { this . scanner . resetTo ( this . tagSourceEnd + 1 , this . javadocEnd ) ; this . index = this . tagSourceEnd + 1 ; this . tagValue = TAG_OTHERS_VALUE ; } return valid ; } protected boolean parseReturn ( ) { createTag ( ) ; return true ; } protected boolean parseTag ( int previousPosition ) throws InvalidInputException { if ( this . htmlTagsPtr >= 0 ) { int ptr = this . htmlTagsPtr ; while ( ptr >= 0 ) { if ( getHtmlTagIndex ( this . htmlTags [ ptr -- ] ) == JAVADOC_CODE_TAGS_ID ) { if ( this . textStart == - 1 ) this . textStart = this . inlineTagStarted ? this . inlineTagStart : previousPosition ; this . inlineTagStarted = false ; return true ; } } } int ptr = this . astPtr ; this . tagSourceStart = previousPosition ; this . scanner . startPosition = this . index ; this . scanner . currentCharacter = readChar ( ) ; switch ( this . scanner . currentCharacter ) { case ' ' : case '*' : case '}' : this . tagSourceEnd = previousPosition ; if ( this . textStart == - 1 ) this . textStart = previousPosition ; return true ; default : if ( ScannerHelper . isWhitespace ( this . scanner . currentCharacter ) ) { this . tagSourceEnd = previousPosition ; if ( this . textStart == - 1 ) this . textStart = previousPosition ; return true ; } break ; } int currentPosition = this . index ; char currentChar = this . scanner . currentCharacter ; while ( currentChar != ' ' && currentChar != '*' && currentChar != '}' && ! ScannerHelper . isWhitespace ( currentChar ) ) { currentPosition = this . index ; currentChar = readChar ( ) ; } this . tagSourceEnd = currentPosition - 1 ; this . scanner . currentCharacter = currentChar ; this . scanner . currentPosition = currentPosition ; char [ ] tagName = this . scanner . getCurrentIdentifierSource ( ) ; int length = tagName . length ; this . index = this . tagSourceEnd + 1 ; this . tagValue = TAG_OTHERS_VALUE ; boolean valid = false ; switch ( tagName [ 0 ] ) { case 'a' : if ( length == TAG_AUTHOR_LENGTH && CharOperation . equals ( TAG_AUTHOR , tagName ) ) { this . tagValue = TAG_AUTHOR_VALUE ; } break ; case 'c' : if ( length == TAG_CATEGORY_LENGTH && CharOperation . equals ( TAG_CATEGORY , tagName ) ) { this . tagValue = TAG_CATEGORY_VALUE ; valid = parseIdentifierTag ( false ) ; } else if ( length == TAG_CODE_LENGTH && this . inlineTagStarted && CharOperation . equals ( TAG_CODE , tagName ) ) { this . tagValue = TAG_CODE_VALUE ; } break ; case 'd' : if ( length == TAG_DEPRECATED_LENGTH && CharOperation . equals ( TAG_DEPRECATED , tagName ) ) { this . deprecated = true ; valid = true ; this . tagValue = TAG_DEPRECATED_VALUE ; } else if ( length == TAG_DOC_ROOT_LENGTH && CharOperation . equals ( TAG_DOC_ROOT , tagName ) ) { valid = true ; this . tagValue = TAG_DOC_ROOT_VALUE ; } break ; case 'e' : if ( length == TAG_EXCEPTION_LENGTH && CharOperation . equals ( TAG_EXCEPTION , tagName ) ) { this . tagValue = TAG_EXCEPTION_VALUE ; valid = parseThrows ( ) ; } break ; case 'i' : if ( length == TAG_INHERITDOC_LENGTH && CharOperation . equals ( TAG_INHERITDOC , tagName ) ) { if ( this . reportProblems ) { recordInheritedPosition ( ( ( ( long ) this . tagSourceStart ) << 32 ) + this . tagSourceEnd ) ; } valid = true ; this . tagValue = TAG_INHERITDOC_VALUE ; } break ; case 'l' : if ( length == TAG_LINK_LENGTH && CharOperation . equals ( TAG_LINK , tagName ) ) { this . tagValue = TAG_LINK_VALUE ; if ( this . inlineTagStarted || ( this . kind & COMPLETION_PARSER ) != 0 ) { valid = parseReference ( ) ; } else { valid = false ; if ( this . reportProblems ) { this . sourceParser . problemReporter ( ) . javadocUnexpectedTag ( this . tagSourceStart , this . tagSourceEnd ) ; } } } else if ( length == TAG_LINKPLAIN_LENGTH && CharOperation . equals ( TAG_LINKPLAIN , tagName ) ) { this . tagValue = TAG_LINKPLAIN_VALUE ; if ( this . inlineTagStarted ) { valid = parseReference ( ) ; } else { valid = false ; if ( this . reportProblems ) { this . sourceParser . problemReporter ( ) . javadocUnexpectedTag ( this . tagSourceStart , this . tagSourceEnd ) ; } } } else if ( length == TAG_LITERAL_LENGTH && this . inlineTagStarted && CharOperation . equals ( TAG_LITERAL , tagName ) ) { this . tagValue = TAG_LITERAL_VALUE ; } break ; case 'p' : if ( length == TAG_PARAM_LENGTH && CharOperation . equals ( TAG_PARAM , tagName ) ) { this . tagValue = TAG_PARAM_VALUE ; valid = parseParam ( ) ; } break ; case 's' : if ( length == TAG_SEE_LENGTH && CharOperation . equals ( TAG_SEE , tagName ) ) { if ( this . inlineTagStarted ) { valid = false ; if ( this . reportProblems ) { this . sourceParser . problemReporter ( ) . javadocUnexpectedTag ( this . tagSourceStart , this . tagSourceEnd ) ; } } else { this . tagValue = TAG_SEE_VALUE ; valid = parseReference ( ) ; } } else if ( length == TAG_SERIAL_LENGTH && CharOperation . equals ( TAG_SERIAL , tagName ) ) { this . tagValue = TAG_SERIAL_VALUE ; } else if ( length == TAG_SERIAL_DATA_LENGTH && CharOperation . equals ( TAG_SERIAL_DATA , tagName ) ) { this . tagValue = TAG_SERIAL_DATA_VALUE ; } else if ( length == TAG_SERIAL_FIELD_LENGTH && CharOperation . equals ( TAG_SERIAL_FIELD , tagName ) ) { this . tagValue = TAG_SERIAL_FIELD_VALUE ; } else if ( length == TAG_SINCE_LENGTH && CharOperation . equals ( TAG_SINCE , tagName ) ) { this . tagValue = TAG_SINCE_VALUE ; } break ; case 'v' : if ( length == TAG_VALUE_LENGTH && CharOperation . equals ( TAG_VALUE , tagName ) ) { this . tagValue = TAG_VALUE_VALUE ; if ( this . sourceLevel >= ClassFileConstants . JDK1_5 ) { if ( this . inlineTagStarted ) { valid = parseReference ( ) ; } else { valid = false ; if ( this . reportProblems ) this . sourceParser . problemReporter ( ) . javadocUnexpectedTag ( this . tagSourceStart , this . tagSourceEnd ) ; } } } else if ( length == TAG_VERSION_LENGTH && CharOperation . equals ( TAG_VERSION , tagName ) ) { this . tagValue = TAG_VERSION_VALUE ; } else { createTag ( ) ; } break ; case 'r' : if ( length == TAG_RETURN_LENGTH && CharOperation . equals ( TAG_RETURN , tagName ) ) { this . tagValue = TAG_RETURN_VALUE ; valid = parseReturn ( ) ; } break ; case 't' : if ( length == TAG_THROWS_LENGTH && CharOperation . equals ( TAG_THROWS , tagName ) ) { this . tagValue = TAG_THROWS_VALUE ; valid = parseThrows ( ) ; } break ; default : createTag ( ) ; break ; } consumeToken ( ) ; this . textStart = - 1 ; if ( valid ) { switch ( this . tagValue ) { case TAG_INHERITDOC_VALUE : case TAG_DEPRECATED_VALUE : createTag ( ) ; break ; } } else if ( this . invalidTagName ) { this . textStart = previousPosition ; } else if ( this . astPtr == ptr ) { createTag ( ) ; } return true ; } protected boolean parseThrows ( ) { boolean valid = super . parseThrows ( ) ; if ( ! valid ) { this . scanner . resetTo ( this . tagSourceEnd + 1 , this . javadocEnd ) ; this . index = this . tagSourceEnd + 1 ; this . tagValue = TAG_OTHERS_VALUE ; } return valid ; } protected boolean pushParamName ( boolean isTypeParam ) { int lineTagStart = this . scanner . getLineNumber ( this . tagSourceStart ) ; FormatJavadocBlock block = new FormatJavadocBlock ( this . tagSourceStart , this . tagSourceEnd , lineTagStart , TAG_PARAM_VALUE ) ; int start = ( int ) ( this . identifierPositionStack [ 0 ] >>> 32 ) ; int lineStart = this . scanner . getLineNumber ( start ) ; FormatJavadocReference reference ; reference = new FormatJavadocReference ( start , ( int ) this . identifierPositionStack [ isTypeParam ? 2 : 0 ] , lineStart ) ; block . reference = reference ; block . sourceEnd = reference . sourceEnd ; pushOnAstStack ( block , true ) ; return true ; } protected boolean pushSeeRef ( Object statement ) { FormatJavadocReference reference = ( FormatJavadocReference ) statement ; int lineTagStart = this . scanner . getLineNumber ( this . tagSourceStart ) ; FormatJavadocBlock block = new FormatJavadocBlock ( this . tagSourceStart , this . tagSourceEnd , lineTagStart , this . tagValue ) ; block . reference = reference ; block . sourceEnd = reference . sourceEnd ; if ( this . inlineTagStarted ) { block . sourceStart = this . inlineTagStart ; FormatJavadocBlock previousBlock = null ; if ( this . astPtr == - 1 ) { int lineStart = this . scanner . getLineNumber ( this . inlineTagStart ) ; previousBlock = new FormatJavadocBlock ( this . inlineTagStart , this . tagSourceEnd , lineStart , NO_TAG_VALUE ) ; previousBlock . sourceEnd = reference . sourceEnd ; pushOnAstStack ( previousBlock , true ) ; } else { previousBlock = ( FormatJavadocBlock ) this . astStack [ this . astPtr ] ; } previousBlock . addBlock ( block , this . htmlTagsPtr == - 1 ? 0 : this . htmlTagsPtr ) ; block . flags |= FormatJavadocBlock . INLINED ; } else { pushOnAstStack ( block , true ) ; } return true ; } protected void pushText ( int start , int end ) { pushText ( start , end , - 1 , this . htmlTagsPtr == - 1 ? 0 : this . htmlTagsPtr ) ; } private void pushText ( int start , int end , int htmlIndex , int htmlDepth ) { FormatJavadocBlock previousBlock = null ; int previousStart = start ; int lineStart = this . scanner . getLineNumber ( start ) ; if ( this . astPtr == - 1 ) { previousBlock = new FormatJavadocBlock ( start , start , lineStart , NO_TAG_VALUE ) ; pushOnAstStack ( previousBlock , true ) ; } else { previousBlock = ( FormatJavadocBlock ) this . astStack [ this . astPtr ] ; previousStart = previousBlock . sourceStart ; } if ( this . inlineTagStarted ) { if ( previousBlock . nodes == null ) { } else { FormatJavadocNode lastNode = previousBlock . nodes [ previousBlock . nodesPtr ] ; while ( lastNode != null && lastNode . isText ( ) ) { lastNode = lastNode . getLastNode ( ) ; } if ( lastNode != null ) { previousBlock = ( FormatJavadocBlock ) lastNode ; previousStart = previousBlock . sourceStart ; } } } FormatJavadocText text = new FormatJavadocText ( start , end - 1 , lineStart , htmlIndex , htmlDepth == - 1 ? 0 : htmlDepth ) ; previousBlock . addText ( text ) ; previousBlock . sourceStart = previousStart ; if ( lineStart == previousBlock . lineStart ) { previousBlock . flags |= FormatJavadocBlock . TEXT_ON_TAG_LINE ; } this . textStart = - 1 ; } protected boolean pushThrowName ( Object typeRef ) { int lineStart = this . scanner . getLineNumber ( this . tagSourceStart ) ; FormatJavadocBlock block = new FormatJavadocBlock ( this . tagSourceStart , this . tagSourceEnd , lineStart , this . tagValue ) ; block . reference = ( FormatJavadocReference ) typeRef ; block . sourceEnd = block . reference . sourceEnd ; pushOnAstStack ( block , true ) ; return true ; } protected void refreshInlineTagPosition ( int previousPosition ) { if ( this . astPtr != - 1 ) { FormatJavadocNode previousBlock = ( FormatJavadocNode ) this . astStack [ this . astPtr ] ; if ( this . inlineTagStarted ) { FormatJavadocNode lastNode = previousBlock ; while ( lastNode != null ) { lastNode . sourceEnd = previousPosition ; lastNode = lastNode . getLastNode ( ) ; } } } } protected void setInlineTagStarted ( boolean started ) { super . setInlineTagStarted ( started ) ; if ( started ) { this . inlineHtmlTagsPtr = this . htmlTagsPtr ; } else { if ( this . htmlTagsPtr > this . inlineHtmlTagsPtr ) { this . htmlTagsPtr = this . inlineHtmlTagsPtr ; } } } public String toString ( ) { StringBuffer buffer = new StringBuffer ( ) ; buffer . append ( "" ) ; buffer . append ( super . toString ( ) ) ; return buffer . toString ( ) ; } public String toDebugString ( ) { if ( this . docComment == null ) { return "No javadoc!" ; } return ( ( FormatJavadoc ) this . docComment ) . toDebugString ( this . source ) ; } protected void updateDocComment ( ) { int length = this . astPtr + 1 ; FormatJavadoc formatJavadoc = new FormatJavadoc ( this . javadocStart , this . javadocEnd , length ) ; if ( length > 0 ) { formatJavadoc . blocks = new FormatJavadocBlock [ length ] ; for ( int i = 0 ; i < length ; i ++ ) { FormatJavadocBlock block = ( FormatJavadocBlock ) this . astStack [ i ] ; block . clean ( ) ; block . update ( this . scanner ) ; formatJavadoc . blocks [ i ] = block ; if ( i == 0 ) { block . flags |= FormatJavadocBlock . FIRST ; } } } formatJavadoc . textStart = this . javadocTextStart ; formatJavadoc . textEnd = this . javadocTextEnd ; formatJavadoc . lineStart = this . scanner . getLineNumber ( this . javadocTextStart ) ; formatJavadoc . lineEnd = this . scanner . getLineNumber ( this . javadocTextEnd ) ; FormatJavadocBlock firstBlock = formatJavadoc . getFirstBlock ( ) ; if ( firstBlock != null ) { firstBlock . setHeaderLine ( formatJavadoc . lineStart ) ; } this . docComment = formatJavadoc ; if ( DefaultCodeFormatter . DEBUG ) { System . out . println ( toDebugString ( ) ) ; } } protected boolean verifyEndLine ( int textPosition ) { return true ; } protected boolean verifySpaceOrEndComment ( ) { return true ; } } </s>