<s> package org . eclipse . jdt . core . dom ; import java . util . Iterator ; 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 . AbstractCommentParser ; import org . eclipse . jdt . internal . compiler . parser . Scanner ; import org . eclipse . jdt . internal . compiler . parser . ScannerHelper ; import org . eclipse . jdt . internal . compiler . parser . TerminalTokens ; class DocCommentParser extends AbstractCommentParser { private Javadoc docComment ; private AST ast ; DocCommentParser ( AST ast , Scanner scanner , boolean check ) { super ( null ) ; this . ast = ast ; this . scanner = scanner ; this . sourceLevel = this . ast . apiLevel ( ) >= AST . JLS3 ? ClassFileConstants . JDK1_5 : ClassFileConstants . JDK1_3 ; this . checkDocComment = check ; this . kind = DOM_PARSER | TEXT_PARSE ; } public Javadoc parse ( int [ ] positions ) { return parse ( positions [ 0 ] , positions [ 1 ] - positions [ 0 ] ) ; } public Javadoc parse ( int start , int length ) { this . source = this . scanner . source ; this . lineEnds = this . scanner . lineEnds ; this . docComment = new Javadoc ( this . ast ) ; if ( this . checkDocComment ) { this . javadocStart = start ; this . javadocEnd = start + length - 1 ; this . firstTagPosition = this . javadocStart ; commentParse ( ) ; } this . docComment . setSourceRange ( start , length ) ; if ( this . ast . apiLevel == AST . JLS2_INTERNAL ) { setComment ( start , length ) ; } return this . docComment ; } private void setComment ( int start , int length ) { this . docComment . setComment ( new String ( this . source , start , length ) ) ; } public String toString ( ) { StringBuffer buffer = new StringBuffer ( ) ; buffer . append ( "javadoc: " ) . append ( this . docComment ) . append ( "n" ) ; buffer . append ( super . toString ( ) ) ; return buffer . toString ( ) ; } protected Object createArgumentReference ( char [ ] name , int dim , boolean isVarargs , Object typeRef , long [ ] dimPositions , long argNamePos ) throws InvalidInputException { try { MethodRefParameter argument = this . ast . newMethodRefParameter ( ) ; ASTNode node = ( ASTNode ) typeRef ; int argStart = node . getStartPosition ( ) ; int argEnd = node . getStartPosition ( ) + node . getLength ( ) - 1 ; if ( dim > 0 ) argEnd = ( int ) dimPositions [ dim - 1 ] ; if ( argNamePos >= 0 ) argEnd = ( int ) argNamePos ; if ( name . length != 0 ) { final SimpleName argName = new SimpleName ( this . ast ) ; argName . internalSetIdentifier ( new String ( name ) ) ; argument . setName ( argName ) ; int argNameStart = ( int ) ( argNamePos >>> 32 ) ; argName . setSourceRange ( argNameStart , argEnd - argNameStart + 1 ) ; } Type argType = null ; if ( node . getNodeType ( ) == ASTNode . PRIMITIVE_TYPE ) { argType = ( PrimitiveType ) node ; } else { Name argTypeName = ( Name ) node ; argType = this . ast . newSimpleType ( argTypeName ) ; argType . setSourceRange ( argStart , node . getLength ( ) ) ; } if ( dim > 0 && ! isVarargs ) { for ( int i = 0 ; i < dim ; i ++ ) { argType = this . ast . newArrayType ( argType ) ; argType . setSourceRange ( argStart , ( ( int ) dimPositions [ i ] ) - argStart + 1 ) ; } } argument . setType ( argType ) ; argument . setSourceRange ( argStart , argEnd - argStart + 1 ) ; return argument ; } catch ( ClassCastException ex ) { throw new InvalidInputException ( ) ; } } protected Object createFieldReference ( Object receiver ) throws InvalidInputException { try { MemberRef fieldRef = this . ast . newMemberRef ( ) ; SimpleName fieldName = new SimpleName ( this . ast ) ; fieldName . internalSetIdentifier ( new String ( this . identifierStack [ 0 ] ) ) ; fieldRef . setName ( fieldName ) ; int start = ( int ) ( this . identifierPositionStack [ 0 ] >>> 32 ) ; int end = ( int ) this . identifierPositionStack [ 0 ] ; fieldName . setSourceRange ( start , end - start + 1 ) ; if ( receiver == null ) { start = this . memberStart ; fieldRef . setSourceRange ( start , end - start + 1 ) ; } else { Name typeRef = ( Name ) receiver ; fieldRef . setQualifier ( typeRef ) ; start = typeRef . getStartPosition ( ) ; end = fieldName . getStartPosition ( ) + fieldName . getLength ( ) - 1 ; fieldRef . setSourceRange ( start , end - start + 1 ) ; } return fieldRef ; } catch ( ClassCastException ex ) { throw new InvalidInputException ( ) ; } } protected Object createMethodReference ( Object receiver , List arguments ) throws InvalidInputException { try { MethodRef methodRef = this . ast . newMethodRef ( ) ; SimpleName methodName = new SimpleName ( this . ast ) ; int length = this . identifierLengthStack [ 0 ] - 1 ; methodName . internalSetIdentifier ( new String ( this . identifierStack [ length ] ) ) ; methodRef . setName ( methodName ) ; int start = ( int ) ( this . identifierPositionStack [ length ] >>> 32 ) ; int end = ( int ) this . identifierPositionStack [ length ] ; methodName . setSourceRange ( start , end - start + 1 ) ; if ( receiver == null ) { start = this . memberStart ; methodRef . setSourceRange ( start , end - start + 1 ) ; } else { Name typeRef = ( Name ) receiver ; methodRef . setQualifier ( typeRef ) ; start = typeRef . getStartPosition ( ) ; } if ( arguments != null ) { Iterator parameters = arguments . listIterator ( ) ; while ( parameters . hasNext ( ) ) { MethodRefParameter param = ( MethodRefParameter ) parameters . next ( ) ; methodRef . parameters ( ) . add ( param ) ; } } methodRef . setSourceRange ( start , this . scanner . getCurrentTokenEndPosition ( ) - start + 1 ) ; return methodRef ; } catch ( ClassCastException ex ) { throw new InvalidInputException ( ) ; } } protected void createTag ( ) { TagElement tagElement = this . ast . newTagElement ( ) ; int position = this . scanner . currentPosition ; this . scanner . resetTo ( this . tagSourceStart , this . tagSourceEnd ) ; StringBuffer tagName = new StringBuffer ( ) ; int start = this . tagSourceStart ; this . scanner . getNextChar ( ) ; while ( this . scanner . currentPosition <= ( this . tagSourceEnd + 1 ) ) { tagName . append ( this . scanner . currentCharacter ) ; this . scanner . getNextChar ( ) ; } tagElement . setTagName ( tagName . toString ( ) ) ; if ( this . inlineTagStarted ) { start = this . inlineTagStart ; TagElement previousTag = null ; if ( this . astPtr == - 1 ) { previousTag = this . ast . newTagElement ( ) ; previousTag . setSourceRange ( start , this . tagSourceEnd - start + 1 ) ; pushOnAstStack ( previousTag , true ) ; } else { previousTag = ( TagElement ) this . astStack [ this . astPtr ] ; } int previousStart = previousTag . getStartPosition ( ) ; previousTag . fragments ( ) . add ( tagElement ) ; previousTag . setSourceRange ( previousStart , this . tagSourceEnd - previousStart + 1 ) ; } else { pushOnAstStack ( tagElement , true ) ; } tagElement . setSourceRange ( start , this . tagSourceEnd - start + 1 ) ; this . scanner . resetTo ( position , this . javadocEnd ) ; } protected Object createTypeReference ( int primitiveToken ) { int size = this . identifierLengthStack [ this . identifierLengthPtr ] ; String [ ] identifiers = new String [ size ] ; int pos = this . identifierPtr - size + 1 ; for ( int i = 0 ; i < size ; i ++ ) { identifiers [ i ] = new String ( this . identifierStack [ pos + i ] ) ; } ASTNode typeRef = null ; if ( primitiveToken == - 1 ) { typeRef = this . ast . internalNewName ( identifiers ) ; } else { switch ( primitiveToken ) { case TerminalTokens . TokenNamevoid : typeRef = this . ast . newPrimitiveType ( PrimitiveType . VOID ) ; break ; case TerminalTokens . TokenNameboolean : typeRef = this . ast . newPrimitiveType ( PrimitiveType . BOOLEAN ) ; break ; case TerminalTokens . TokenNamebyte : typeRef = this . ast . newPrimitiveType ( PrimitiveType . BYTE ) ; break ; case TerminalTokens . TokenNamechar : typeRef = this . ast . newPrimitiveType ( PrimitiveType . CHAR ) ; break ; case TerminalTokens . TokenNamedouble : typeRef = this . ast . newPrimitiveType ( PrimitiveType . DOUBLE ) ; break ; case TerminalTokens . TokenNamefloat : typeRef = this . ast . newPrimitiveType ( PrimitiveType . FLOAT ) ; break ; case TerminalTokens . TokenNameint : typeRef = this . ast . newPrimitiveType ( PrimitiveType . INT ) ; break ; case TerminalTokens . TokenNamelong : typeRef = this . ast . newPrimitiveType ( PrimitiveType . LONG ) ; break ; case TerminalTokens . TokenNameshort : typeRef = this . ast . newPrimitiveType ( PrimitiveType . SHORT ) ; break ; default : return null ; } } int start = ( int ) ( this . identifierPositionStack [ pos ] >>> 32 ) ; if ( size > 1 ) { Name name = ( Name ) typeRef ; int nameIndex = size ; for ( int i = this . identifierPtr ; i > pos ; i -- , nameIndex -- ) { int s = ( int ) ( this . identifierPositionStack [ i ] >>> 32 ) ; int e = ( int ) this . identifierPositionStack [ i ] ; name . index = nameIndex ; SimpleName simpleName = ( ( QualifiedName ) name ) . getName ( ) ; simpleName . index = nameIndex ; simpleName . setSourceRange ( s , e - s + 1 ) ; name . setSourceRange ( start , e - start + 1 ) ; name = ( ( QualifiedName ) name ) . getQualifier ( ) ; } int end = ( int ) this . identifierPositionStack [ pos ] ; name . setSourceRange ( start , end - start + 1 ) ; name . index = nameIndex ; } else { int end = ( int ) this . identifierPositionStack [ pos ] ; typeRef . setSourceRange ( start , end - start + 1 ) ; } return typeRef ; } protected boolean parseIdentifierTag ( boolean report ) { if ( super . parseIdentifierTag ( report ) ) { createTag ( ) ; this . index = this . tagSourceEnd + 1 ; this . scanner . resetTo ( this . index , this . javadocEnd ) ; return true ; } return false ; } protected boolean parseReturn ( ) { createTag ( ) ; return true ; } protected boolean parseTag ( int previousPosition ) throws InvalidInputException { int currentPosition = this . index ; int token = readTokenAndConsume ( ) ; char [ ] tagName = CharOperation . NO_CHAR ; if ( currentPosition == this . scanner . startPosition ) { this . tagSourceStart = this . scanner . getCurrentTokenStartPosition ( ) ; this . tagSourceEnd = this . scanner . getCurrentTokenEndPosition ( ) ; tagName = this . scanner . getCurrentIdentifierSource ( ) ; } else { this . tagSourceEnd = currentPosition - 1 ; } if ( this . scanner . currentCharacter != ' ' && ! ScannerHelper . isWhitespace ( this . scanner . currentCharacter ) ) { tagNameToken : while ( token != TerminalTokens . TokenNameEOF && this . index < this . scanner . eofPosition ) { int length = tagName . length ; switch ( this . scanner . currentCharacter ) { case '}' : case '*' : case '!' : case '#' : case '%' : case '&' : case '\'' : case '"' : case ':' : case '<' : case '>' : break tagNameToken ; case '-' : System . arraycopy ( tagName , 0 , tagName = new char [ length + 1 ] , 0 , length ) ; tagName [ length ] = this . scanner . currentCharacter ; break ; default : if ( this . scanner . currentCharacter == ' ' || ScannerHelper . isWhitespace ( this . scanner . currentCharacter ) ) { break tagNameToken ; } token = readTokenAndConsume ( ) ; char [ ] ident = this . scanner . getCurrentIdentifierSource ( ) ; System . arraycopy ( tagName , 0 , tagName = new char [ length + ident . length ] , 0 , length ) ; System . arraycopy ( ident , 0 , tagName , length , ident . length ) ; break ; } this . tagSourceEnd = this . scanner . getCurrentTokenEndPosition ( ) ; this . scanner . getNextChar ( ) ; this . index = this . scanner . currentPosition ; } } int length = tagName . length ; this . index = this . tagSourceEnd + 1 ; this . scanner . currentPosition = this . tagSourceEnd + 1 ; this . tagSourceStart = previousPosition ; if ( tagName . length == 0 ) { return false ; } this . tagValue = NO_TAG_VALUE ; boolean valid = true ; switch ( token ) { case TerminalTokens . TokenNameIdentifier : switch ( tagName [ 0 ] ) { case 'c' : if ( length == TAG_CATEGORY_LENGTH && CharOperation . equals ( TAG_CATEGORY , tagName ) ) { this . tagValue = TAG_CATEGORY_VALUE ; valid = parseIdentifierTag ( false ) ; } else { this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; case 'd' : if ( length == TAG_DEPRECATED_LENGTH && CharOperation . equals ( TAG_DEPRECATED , tagName ) ) { this . deprecated = true ; this . tagValue = TAG_DEPRECATED_VALUE ; } else { this . tagValue = TAG_OTHERS_VALUE ; } createTag ( ) ; break ; case 'i' : if ( length == TAG_INHERITDOC_LENGTH && CharOperation . equals ( TAG_INHERITDOC , tagName ) ) { if ( this . reportProblems ) { recordInheritedPosition ( ( ( ( long ) this . tagSourceStart ) << 32 ) + this . tagSourceEnd ) ; } this . tagValue = TAG_INHERITDOC_VALUE ; } else { this . tagValue = TAG_OTHERS_VALUE ; } createTag ( ) ; break ; case 'p' : if ( length == TAG_PARAM_LENGTH && CharOperation . equals ( TAG_PARAM , tagName ) ) { this . tagValue = TAG_PARAM_VALUE ; valid = parseParam ( ) ; } else { this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; case 'e' : if ( length == TAG_EXCEPTION_LENGTH && CharOperation . equals ( TAG_EXCEPTION , tagName ) ) { this . tagValue = TAG_EXCEPTION_VALUE ; valid = parseThrows ( ) ; } else { this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; case 's' : if ( length == TAG_SEE_LENGTH && CharOperation . equals ( TAG_SEE , tagName ) ) { this . tagValue = TAG_SEE_VALUE ; if ( this . inlineTagStarted ) { valid = false ; } else { valid = parseReference ( ) ; } } else { this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; case 'l' : if ( length == TAG_LINK_LENGTH && CharOperation . equals ( TAG_LINK , tagName ) ) { this . tagValue = TAG_LINK_VALUE ; } else if ( length == TAG_LINKPLAIN_LENGTH && CharOperation . equals ( TAG_LINKPLAIN , tagName ) ) { this . tagValue = TAG_LINKPLAIN_VALUE ; } if ( this . tagValue != NO_TAG_VALUE ) { if ( this . inlineTagStarted ) { valid = parseReference ( ) ; } else { valid = false ; } } else { this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; case 'v' : if ( this . sourceLevel >= ClassFileConstants . JDK1_5 && length == TAG_VALUE_LENGTH && CharOperation . equals ( TAG_VALUE , tagName ) ) { this . tagValue = TAG_VALUE_VALUE ; if ( this . inlineTagStarted ) { valid = parseReference ( ) ; } else { valid = false ; } } else { this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; default : this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; } break ; case TerminalTokens . TokenNamereturn : this . tagValue = TAG_RETURN_VALUE ; valid = parseReturn ( ) ; break ; case TerminalTokens . TokenNamethrows : this . tagValue = TAG_THROWS_VALUE ; valid = parseThrows ( ) ; break ; case TerminalTokens . TokenNameabstract : case TerminalTokens . TokenNameassert : case TerminalTokens . TokenNameboolean : case TerminalTokens . TokenNamebreak : case TerminalTokens . TokenNamebyte : case TerminalTokens . TokenNamecase : case TerminalTokens . TokenNamecatch : case TerminalTokens . TokenNamechar : case TerminalTokens . TokenNameclass : case TerminalTokens . TokenNamecontinue : case TerminalTokens . TokenNamedefault : case TerminalTokens . TokenNamedo : case TerminalTokens . TokenNamedouble : case TerminalTokens . TokenNameelse : case TerminalTokens . TokenNameextends : case TerminalTokens . TokenNamefalse : case TerminalTokens . TokenNamefinal : case TerminalTokens . TokenNamefinally : case TerminalTokens . TokenNamefloat : case TerminalTokens . TokenNamefor : case TerminalTokens . TokenNameif : case TerminalTokens . TokenNameimplements : case TerminalTokens . TokenNameimport : case TerminalTokens . TokenNameinstanceof : case TerminalTokens . TokenNameint : case TerminalTokens . TokenNameinterface : case TerminalTokens . TokenNamelong : case TerminalTokens . TokenNamenative : case TerminalTokens . TokenNamenew : case TerminalTokens . TokenNamenull : case TerminalTokens . TokenNamepackage : case TerminalTokens . TokenNameprivate : case TerminalTokens . TokenNameprotected : case TerminalTokens . TokenNamepublic : case TerminalTokens . TokenNameshort : case TerminalTokens . TokenNamestatic : case TerminalTokens . TokenNamestrictfp : case TerminalTokens . TokenNamesuper : case TerminalTokens . TokenNameswitch : case TerminalTokens . TokenNamesynchronized : case TerminalTokens . TokenNamethis : case TerminalTokens . TokenNamethrow : case TerminalTokens . TokenNametransient : case TerminalTokens . TokenNametrue : case TerminalTokens . TokenNametry : case TerminalTokens . TokenNamevoid : case TerminalTokens . TokenNamevolatile : case TerminalTokens . TokenNamewhile : case TerminalTokens . TokenNameenum : case TerminalTokens . TokenNameconst : case TerminalTokens . TokenNamegoto : this . tagValue = TAG_OTHERS_VALUE ; createTag ( ) ; break ; } this . textStart = this . index ; return valid ; } protected boolean pushParamName ( boolean isTypeParam ) { int idIndex = isTypeParam ? 1 : 0 ; final SimpleName name = new SimpleName ( this . ast ) ; name . internalSetIdentifier ( new String ( this . identifierStack [ idIndex ] ) ) ; int nameStart = ( int ) ( this . identifierPositionStack [ idIndex ] >>> 32 ) ; int nameEnd = ( int ) ( this . identifierPositionStack [ idIndex ] & 0x00000000FFFFFFFFL ) ; name . setSourceRange ( nameStart , nameEnd - nameStart + 1 ) ; TagElement paramTag = this . ast . newTagElement ( ) ; paramTag . setTagName ( TagElement . TAG_PARAM ) ; if ( isTypeParam ) { TextElement text = this . ast . newTextElement ( ) ; text . setText ( new String ( this . identifierStack [ 0 ] ) ) ; int txtStart = ( int ) ( this . identifierPositionStack [ 0 ] >>> 32 ) ; int txtEnd = ( int ) ( this . identifierPositionStack [ 0 ] & 0x00000000FFFFFFFFL ) ; text . setSourceRange ( txtStart , txtEnd - txtStart + 1 ) ; paramTag . fragments ( ) . add ( text ) ; paramTag . fragments ( ) . add ( name ) ; text = this . ast . newTextElement ( ) ; text . setText ( new String ( this . identifierStack [ 2 ] ) ) ; txtStart = ( int ) ( this . identifierPositionStack [ 2 ] >>> 32 ) ; txtEnd = ( int ) ( this . identifierPositionStack [ 2 ] & 0x00000000FFFFFFFFL ) ; text . setSourceRange ( txtStart , txtEnd - txtStart + 1 ) ; paramTag . fragments ( ) . add ( text ) ; paramTag . setSourceRange ( this . tagSourceStart , txtEnd - this . tagSourceStart + 1 ) ; } else { paramTag . setSourceRange ( this . tagSourceStart , nameEnd - this . tagSourceStart + 1 ) ; paramTag . fragments ( ) . add ( name ) ; } pushOnAstStack ( paramTag , true ) ; return true ; } protected boolean pushSeeRef ( Object statement ) { TagElement seeTag = this . ast . newTagElement ( ) ; ASTNode node = ( ASTNode ) statement ; seeTag . fragments ( ) . add ( node ) ; int end = node . getStartPosition ( ) + node . getLength ( ) - 1 ; if ( this . inlineTagStarted ) { seeTag . setSourceRange ( this . inlineTagStart , end - this . inlineTagStart + 1 ) ; switch ( this . tagValue ) { case TAG_LINK_VALUE : seeTag . setTagName ( TagElement . TAG_LINK ) ; break ; case TAG_LINKPLAIN_VALUE : seeTag . setTagName ( TagElement . TAG_LINKPLAIN ) ; break ; case TAG_VALUE_VALUE : seeTag . setTagName ( TagElement . TAG_VALUE ) ; break ; } TagElement previousTag = null ; int previousStart = this . inlineTagStart ; if ( this . astPtr == - 1 ) { previousTag = this . ast . newTagElement ( ) ; pushOnAstStack ( previousTag , true ) ; } else { previousTag = ( TagElement ) this . astStack [ this . astPtr ] ; previousStart = previousTag . getStartPosition ( ) ; } previousTag . fragments ( ) . add ( seeTag ) ; previousTag . setSourceRange ( previousStart , end - previousStart + 1 ) ; } else { seeTag . setTagName ( TagElement . TAG_SEE ) ; seeTag . setSourceRange ( this . tagSourceStart , end - this . tagSourceStart + 1 ) ; pushOnAstStack ( seeTag , true ) ; } return true ; } protected void pushText ( int start , int end ) { TextElement text = this . ast . newTextElement ( ) ; text . setText ( new String ( this . source , start , end - start ) ) ; text . setSourceRange ( start , end - start ) ; TagElement previousTag = null ; int previousStart = start ; if ( this . astPtr == - 1 ) { previousTag = this . ast . newTagElement ( ) ; previousTag . setSourceRange ( start , end - start ) ; pushOnAstStack ( previousTag , true ) ; } else { previousTag = ( TagElement ) this . astStack [ this . astPtr ] ; previousStart = previousTag . getStartPosition ( ) ; } List fragments = previousTag . fragments ( ) ; if ( this . inlineTagStarted ) { int size = fragments . size ( ) ; if ( size == 0 ) { TagElement inlineTag = this . ast . newTagElement ( ) ; fragments . add ( inlineTag ) ; previousTag = inlineTag ; } else { ASTNode lastFragment = ( ASTNode ) fragments . get ( size - 1 ) ; if ( lastFragment . getNodeType ( ) == ASTNode . TAG_ELEMENT ) { previousTag = ( TagElement ) lastFragment ; previousStart = previousTag . getStartPosition ( ) ; } } } previousTag . fragments ( ) . add ( text ) ; previousTag . setSourceRange ( previousStart , end - previousStart ) ; this . textStart = - 1 ; } protected boolean pushThrowName ( Object typeRef ) { TagElement throwsTag = this . ast . newTagElement ( ) ; switch ( this . tagValue ) { case TAG_THROWS_VALUE : throwsTag . setTagName ( TagElement . TAG_THROWS ) ; break ; case TAG_EXCEPTION_VALUE : throwsTag . setTagName ( TagElement . TAG_EXCEPTION ) ; break ; } throwsTag . setSourceRange ( this . tagSourceStart , this . scanner . getCurrentTokenEndPosition ( ) - this . tagSourceStart + 1 ) ; throwsTag . fragments ( ) . add ( typeRef ) ; pushOnAstStack ( throwsTag , true ) ; return true ; } protected void refreshInlineTagPosition ( int previousPosition ) { if ( this . astPtr != - 1 ) { TagElement previousTag = ( TagElement ) this . astStack [ this . astPtr ] ; if ( this . inlineTagStarted ) { int previousStart = previousTag . getStartPosition ( ) ; previousTag . setSourceRange ( previousStart , previousPosition - previousStart + 1 ) ; if ( previousTag . fragments ( ) . size ( ) > 0 ) { ASTNode inlineTag = ( ASTNode ) previousTag . fragments ( ) . get ( previousTag . fragments ( ) . size ( ) - 1 ) ; if ( inlineTag . getNodeType ( ) == ASTNode . TAG_ELEMENT ) { int inlineStart = inlineTag . getStartPosition ( ) ; inlineTag . setSourceRange ( inlineStart , previousPosition - inlineStart + 1 ) ; } } } } } protected void updateDocComment ( ) { for ( int idx = 0 ; idx <= this . astPtr ; idx ++ ) { this . docComment . tags ( ) . add ( this . astStack [ idx ] ) ; } } } </s>