1 11 package org.eclipse.jdt.internal.compiler.parser; 12 13 import java.util.List ; 14 15 import org.eclipse.jdt.core.compiler.CharOperation; 16 import org.eclipse.jdt.core.compiler.InvalidInputException; 17 import org.eclipse.jdt.internal.compiler.ast.*; 18 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 19 import org.eclipse.jdt.internal.compiler.util.Util; 20 21 24 public class JavadocParser extends AbstractCommentParser { 25 26 public Javadoc docComment; 28 29 private int invalidParamReferencesPtr = -1; 32 private ASTNode[] invalidParamReferencesStack; 33 34 private long validValuePositions, invalidValuePositions; 37 38 public JavadocParser(Parser sourceParser) { 39 super(sourceParser); 40 this.kind = COMPIL_PARSER | TEXT_VERIF; 41 } 42 43 49 public boolean checkDeprecation(int commentPtr) { 50 51 this.javadocStart = this.sourceParser.scanner.commentStarts[commentPtr]; 53 this.javadocEnd = this.sourceParser.scanner.commentStops[commentPtr]-1; 54 this.firstTagPosition = this.sourceParser.scanner.commentTagStarts[commentPtr]; 55 this.validValuePositions = -1; 56 this.invalidValuePositions = -1; 57 58 if (this.checkDocComment) { 60 this.docComment = new Javadoc(javadocStart, javadocEnd); 61 } else { 62 this.docComment = null; 63 } 64 65 if (this.firstTagPosition == 0) { 67 switch (this.kind & PARSER_KIND) { 68 case COMPIL_PARSER: 69 case SOURCE_PARSER: 70 return false; 71 } 72 } 73 74 try { 76 this.source = this.sourceParser.scanner.source; 77 if (this.checkDocComment) { 78 this.scanner.lineEnds = this.sourceParser.scanner.lineEnds; 80 this.scanner.linePtr = this.sourceParser.scanner.linePtr; 81 this.lineEnds = this.scanner.lineEnds; 82 commentParse(); 83 } else { 84 85 Scanner sourceScanner = this.sourceParser.scanner; 87 int firstLineNumber = Util.getLineNumber(javadocStart, sourceScanner.lineEnds, 0, sourceScanner.linePtr); 88 int lastLineNumber = Util.getLineNumber(javadocEnd, sourceScanner.lineEnds, 0, sourceScanner.linePtr); 89 this.index = javadocStart +3; 90 91 this.deprecated = false; 93 nextLine : for (int line = firstLineNumber; line <= lastLineNumber; line++) { 94 int lineStart = line == firstLineNumber 95 ? javadocStart + 3 : this.sourceParser.scanner.getLineStart(line); 97 this.index = lineStart; 98 this.lineEnd = line == lastLineNumber 99 ? javadocEnd - 2 : this.sourceParser.scanner.getLineEnd(line); 101 nextCharacter : while (this.index < this.lineEnd) { 102 char c = readChar(); switch (c) { 104 case '*' : 105 case '\u000c' : 106 case ' ' : 107 case '\t' : 108 case '\n' : 109 case '\r' : 110 continue nextCharacter; 112 case '@' : 113 parseSimpleTag(); 114 if (this.tagValue == TAG_DEPRECATED_VALUE) { 115 if (this.abort) break nextCharacter; 116 } 117 } 118 continue nextLine; 119 } 120 } 121 return this.deprecated; 122 } 123 } finally { 124 this.source = null; } 126 return this.deprecated; 127 } 128 129 132 protected Object createArgumentReference(char[] name, int dim, boolean isVarargs, Object typeRef, long[] dimPositions, long argNamePos) throws InvalidInputException { 133 try { 134 TypeReference argTypeRef = (TypeReference) typeRef; 135 if (dim > 0) { 136 long pos = (((long) argTypeRef.sourceStart) << 32) + argTypeRef.sourceEnd; 137 if (typeRef instanceof JavadocSingleTypeReference) { 138 JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef; 139 argTypeRef = new JavadocArraySingleTypeReference(singleRef.token, dim, pos); 140 } else { 141 JavadocQualifiedTypeReference qualifRef = (JavadocQualifiedTypeReference) typeRef; 142 argTypeRef = new JavadocArrayQualifiedTypeReference(qualifRef, dim); 143 } 144 } 145 int argEnd = argTypeRef.sourceEnd; 146 if (dim > 0) { 147 argEnd = (int) dimPositions[dim-1]; 148 if (isVarargs) { 149 argTypeRef.bits |= ASTNode.IsVarArgs; } 151 } 152 if (argNamePos >= 0) argEnd = (int) argNamePos; 153 return new JavadocArgumentExpression(name, argTypeRef.sourceStart, argEnd, argTypeRef); 154 } 155 catch (ClassCastException ex) { 156 throw new InvalidInputException(); 157 } 158 } 159 162 protected Object createFieldReference(Object receiver) throws InvalidInputException { 163 try { 164 TypeReference typeRef = (TypeReference) receiver; 166 if (typeRef == null) { 167 char[] name = this.sourceParser.compilationUnit.getMainTypeName(); 168 typeRef = new JavadocImplicitTypeReference(name, this.memberStart); 169 } 170 JavadocFieldReference field = new JavadocFieldReference(this.identifierStack[0], this.identifierPositionStack[0]); 172 field.receiver = typeRef; 173 field.tagSourceStart = this.tagSourceStart; 174 field.tagSourceEnd = this.tagSourceEnd; 175 field.tagValue = this.tagValue; 176 return field; 177 } 178 catch (ClassCastException ex) { 179 throw new InvalidInputException(); 180 } 181 } 182 185 protected Object createMethodReference(Object receiver, List arguments) throws InvalidInputException { 186 try { 187 TypeReference typeRef = (TypeReference) receiver; 189 boolean isConstructor = false; 191 int length = this.identifierLengthStack[0]; if (typeRef == null) { 193 char[] name = this.sourceParser.compilationUnit.getMainTypeName(); 194 TypeDeclaration typeDecl = getParsedTypeDeclaration(); 195 if (typeDecl != null) { 196 name = typeDecl.name; 197 } 198 isConstructor = CharOperation.equals(this.identifierStack[length-1], name); 199 typeRef = new JavadocImplicitTypeReference(name, this.memberStart); 200 } else { 201 if (typeRef instanceof JavadocSingleTypeReference) { 202 char[] name = ((JavadocSingleTypeReference)typeRef).token; 203 isConstructor = CharOperation.equals(this.identifierStack[length-1], name); 204 } else if (typeRef instanceof JavadocQualifiedTypeReference) { 205 char[][] tokens = ((JavadocQualifiedTypeReference)typeRef).tokens; 206 int last = tokens.length-1; 207 isConstructor = CharOperation.equals(this.identifierStack[length-1], tokens[last]); 208 if (isConstructor) { 209 boolean valid = true; 210 if (valid) { 211 for (int i=0; i<length-1 && valid; i++) { 212 valid = CharOperation.equals(this.identifierStack[i], tokens[i]); 213 } 214 } 215 if (!valid) { 216 if (this.reportProblems) { 217 this.sourceParser.problemReporter().javadocInvalidMemberTypeQualification((int)(this.identifierPositionStack[0]>>>32), (int)this.identifierPositionStack[length-1], -1); 218 } 219 return null; 220 } 221 } 222 } else { 223 throw new InvalidInputException(); 224 } 225 } 226 if (arguments == null) { 228 if (isConstructor) { 229 JavadocAllocationExpression allocation = new JavadocAllocationExpression(this.identifierPositionStack[length-1]); 230 allocation.type = typeRef; 231 allocation.tagValue = this.tagValue; 232 allocation.sourceEnd = this.scanner.getCurrentTokenEndPosition(); 233 if (length == 1) { 234 allocation.qualification = new char[][] { this.identifierStack[0] }; 235 } else { 236 System.arraycopy(this.identifierStack, 0, allocation.qualification = new char[length][], 0, length); 237 allocation.sourceStart = (int) (this.identifierPositionStack[0] >>> 32); 238 } 239 allocation.memberStart = this.memberStart; 240 return allocation; 241 } else { 242 JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[length-1], this.identifierPositionStack[length-1]); 243 msg.receiver = typeRef; 244 msg.tagValue = this.tagValue; 245 msg.sourceEnd = this.scanner.getCurrentTokenEndPosition(); 246 return msg; 247 } 248 } else { 249 JavadocArgumentExpression[] expressions = new JavadocArgumentExpression[arguments.size()]; 250 arguments.toArray(expressions); 251 if (isConstructor) { 252 JavadocAllocationExpression allocation = new JavadocAllocationExpression(this.identifierPositionStack[length-1]); 253 allocation.arguments = expressions; 254 allocation.type = typeRef; 255 allocation.tagValue = this.tagValue; 256 allocation.sourceEnd = this.scanner.getCurrentTokenEndPosition(); 257 if (length == 1) { 258 allocation.qualification = new char[][] { this.identifierStack[0] }; 259 } else { 260 System.arraycopy(this.identifierStack, 0, allocation.qualification = new char[length][], 0, length); 261 allocation.sourceStart = (int) (this.identifierPositionStack[0] >>> 32); 262 } 263 allocation.memberStart = this.memberStart; 264 return allocation; 265 } else { 266 JavadocMessageSend msg = new JavadocMessageSend(this.identifierStack[length-1], this.identifierPositionStack[length-1], expressions); 267 msg.receiver = typeRef; 268 msg.tagValue = this.tagValue; 269 msg.sourceEnd = this.scanner.getCurrentTokenEndPosition(); 270 return msg; 271 } 272 } 273 } 274 catch (ClassCastException ex) { 275 throw new InvalidInputException(); 276 } 277 } 278 281 protected Object createReturnStatement() { 282 return new JavadocReturnStatement(this.scanner.getCurrentTokenStartPosition(), 283 this.scanner.getCurrentTokenEndPosition()); 284 } 285 286 289 protected void createTag() { 290 this.tagValue = TAG_OTHERS_VALUE; 291 } 292 293 296 protected Object createTypeReference(int primitiveToken) { 297 TypeReference typeRef = null; 298 int size = this.identifierLengthStack[this.identifierLengthPtr]; 299 if (size == 1) { typeRef = new JavadocSingleTypeReference( 301 this.identifierStack[this.identifierPtr], 302 this.identifierPositionStack[this.identifierPtr], 303 this.tagSourceStart, 304 this.tagSourceEnd); 305 } else if (size > 1) { char[][] tokens = new char[size][]; 307 System.arraycopy(this.identifierStack, this.identifierPtr - size + 1, tokens, 0, size); 308 long[] positions = new long[size]; 309 System.arraycopy(this.identifierPositionStack, this.identifierPtr - size + 1, positions, 0, size); 310 typeRef = new JavadocQualifiedTypeReference(tokens, positions, this.tagSourceStart, this.tagSourceEnd); 311 } 312 return typeRef; 313 } 314 315 318 protected TypeDeclaration getParsedTypeDeclaration() { 319 int ptr = this.sourceParser.astPtr; 320 while (ptr >= 0) { 321 Object node = this.sourceParser.astStack[ptr]; 322 if (node instanceof TypeDeclaration) { 323 TypeDeclaration typeDecl = (TypeDeclaration) node; 324 if (typeDecl.bodyEnd == 0) { return typeDecl; 326 } 327 } 328 ptr--; 329 } 330 return null; 331 } 332 333 336 protected boolean parseReturn() { 337 if (this.returnStatement == null) { 338 this.returnStatement = createReturnStatement(); 339 return true; 340 } 341 if (this.reportProblems) { 342 this.sourceParser.problemReporter().javadocDuplicatedReturnTag( 343 this.scanner.getCurrentTokenStartPosition(), 344 this.scanner.getCurrentTokenEndPosition()); 345 } 346 return false; 347 } 348 349 350 protected void parseSimpleTag() { 351 352 char first = this.source[this.index++]; 355 if (first == '\\' && this.source[this.index] == 'u') { 356 int c1, c2, c3, c4; 357 int pos = this.index; 358 this.index++; 359 while (this.source[this.index] == 'u') 360 this.index++; 361 if (!(((c1 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c1 < 0) 362 || ((c2 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c2 < 0) 363 || ((c3 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c3 < 0) || ((c4 = ScannerHelper.getNumericValue(this.source[this.index++])) > 15 || c4 < 0))) { 364 first = (char) (((c1 * 16 + c2) * 16 + c3) * 16 + c4); 365 } else { 366 this.index = pos; 367 } 368 } 369 370 switch (first) { 372 case 'd': 373 if ((readChar() == 'e') && 374 (readChar() == 'p') && (readChar() == 'r') && 375 (readChar() == 'e') && (readChar() == 'c') && 376 (readChar() == 'a') && (readChar() == 't') && 377 (readChar() == 'e') && (readChar() == 'd')) { 378 char c = readChar(); 380 if (ScannerHelper.isWhitespace(c) || c == '*') { 381 this.abort = true; 382 this.deprecated = true; 383 this.tagValue = TAG_DEPRECATED_VALUE; 384 } 385 } 386 break; 387 } 388 } 389 390 protected boolean parseTag(int previousPosition) throws InvalidInputException { 391 boolean valid = false; 392 393 int currentPosition = this.index; 395 int token = readTokenAndConsume(); 396 if (currentPosition != this.scanner.startPosition) { 397 this.tagSourceStart = previousPosition; 398 this.tagSourceEnd = currentPosition; 399 if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, this.tagSourceEnd); 400 return false; 401 } 402 if (this.index >= this.scanner.eofPosition) { 403 this.tagSourceStart = previousPosition; 404 this.tagSourceEnd = this.tokenPreviousPosition; 405 if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, this.tagSourceEnd); 406 return false; 407 } 408 this.tagSourceStart = this.scanner.getCurrentTokenStartPosition(); 409 this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition(); 410 char[] tagName = this.scanner.getCurrentIdentifierSource(); 411 412 if (this.scanner.currentCharacter != ' ' && !ScannerHelper.isWhitespace(this.scanner.currentCharacter)) { 415 boolean validTag = true; 416 tagNameToken: while (token != TerminalTokens.TokenNameEOF && this.index < this.scanner.eofPosition) { 417 int length = tagName.length; 418 switch (this.scanner.currentCharacter) { 420 case '}': 421 case '*': break tagNameToken; 423 case '!': 424 case '#': 425 case '%': 426 case '&': 427 case '\'': 428 case '"': 429 case ':': 430 case '<': 431 case '>': 432 case '@': 433 validTag = false; 434 this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition(); 435 this.index = this.scanner.currentPosition; 436 break; 437 case '-': System.arraycopy(tagName, 0, tagName = new char[length+1], 0, length); 439 tagName[length] = this.scanner.currentCharacter; 440 this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition(); 441 this.index = this.scanner.currentPosition; 442 break; 443 default: 444 if (this.scanner.currentCharacter == ' ' || ScannerHelper.isWhitespace(this.scanner.currentCharacter)) { 445 break tagNameToken; 446 } 447 token = readTokenAndConsume(); 448 char[] ident = this.scanner.getCurrentIdentifierSource(); 449 System.arraycopy(tagName, 0, tagName = new char[length+ident.length], 0, length); 450 System.arraycopy(ident, 0, tagName, length, ident.length); 451 this.tagSourceEnd = this.scanner.getCurrentTokenEndPosition(); 452 break; 453 } 454 this.scanner.getNextChar(); 455 } 456 if (!validTag) { 457 if (this.reportProblems) this.sourceParser.problemReporter().javadocInvalidTag(this.tagSourceStart, this.tagSourceEnd); 458 return false; 459 } 460 } 461 int length = tagName.length; 462 if (length == 0) return false; this.index = this.tagSourceEnd+1; 464 this.scanner.currentPosition = this.tagSourceEnd+1; 465 466 this.tagValue = NO_TAG_VALUE; 468 switch (token) { 469 case TerminalTokens.TokenNameIdentifier : 470 switch (tagName[0]) { 471 case 'c': 472 if (length == TAG_CATEGORY_LENGTH && CharOperation.equals(TAG_CATEGORY, tagName)) { 473 this.tagValue = TAG_CATEGORY_VALUE; 474 valid = parseIdentifierTag(false); } 476 break; 477 case 'd': 478 if (length == TAG_DEPRECATED_LENGTH && CharOperation.equals(TAG_DEPRECATED, tagName)) { 479 this.deprecated = true; 480 valid = true; 481 this.tagValue = TAG_DEPRECATED_VALUE; 482 } 483 break; 484 case 'e': 485 if (length == TAG_EXCEPTION_LENGTH && CharOperation.equals(TAG_EXCEPTION, tagName)) { 486 this.tagValue = TAG_EXCEPTION_VALUE; 487 valid = parseThrows(); 488 } 489 break; 490 case 'i': 491 if (length == TAG_INHERITDOC_LENGTH && CharOperation.equals(TAG_INHERITDOC, tagName)) { 492 if (this.astPtr==-1) { 498 this.inheritedPositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd; 499 } 500 valid = true; 501 this.tagValue = TAG_INHERITDOC_VALUE; 502 } 503 break; 504 case 'l': 505 if (length == TAG_LINK_LENGTH && CharOperation.equals(TAG_LINK, tagName)) { 506 this.tagValue = TAG_LINK_VALUE; 507 if (this.inlineTagStarted || (this.kind & COMPLETION_PARSER) != 0) { 508 valid= parseReference(); 509 } else { 510 valid = false; 513 if (this.reportProblems) { 514 this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); 515 } 516 } 517 } else if (length == TAG_LINKPLAIN_LENGTH && CharOperation.equals(TAG_LINKPLAIN, tagName)) { 518 this.tagValue = TAG_LINKPLAIN_VALUE; 519 if (this.inlineTagStarted) { 520 valid = parseReference(); 521 } else { 522 valid = false; 523 if (this.reportProblems) { 524 this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); 525 } 526 } 527 } 528 break; 529 case 'p': 530 if (length == TAG_PARAM_LENGTH && CharOperation.equals(TAG_PARAM, tagName)) { 531 this.tagValue = TAG_PARAM_VALUE; 532 valid = parseParam(); 533 } 534 break; 535 case 's': 536 if (length == TAG_SEE_LENGTH && CharOperation.equals(TAG_SEE, tagName)) { 537 if (this.inlineTagStarted) { 538 valid = false; 541 if (this.reportProblems) { 542 this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); 543 } 544 } else { 545 this.tagValue = TAG_SEE_VALUE; 546 valid = parseReference(); 547 } 548 } 549 break; 550 case 'v': 551 if (length == TAG_VALUE_LENGTH && CharOperation.equals(TAG_VALUE, tagName)) { 552 this.tagValue = TAG_VALUE_VALUE; 553 if (this.sourceLevel >= ClassFileConstants.JDK1_5) { 554 if (this.inlineTagStarted) { 555 valid = parseReference(); 556 } else { 557 valid = false; 558 if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); 559 } 560 } else { 561 if (this.validValuePositions == -1) { 562 if (this.invalidValuePositions != -1) { 563 if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag((int) (this.invalidValuePositions>>>32), (int) this.invalidValuePositions); 564 } 565 if (valid) { 566 this.validValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd; 567 this.invalidValuePositions = -1; 568 } else { 569 this.invalidValuePositions = (((long) this.tagSourceStart) << 32) + this.tagSourceEnd; 570 } 571 } else { 572 if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); 573 } 574 } 575 } else { 576 createTag(); 577 } 578 break; 579 default: 580 createTag(); 581 break; 582 } 583 break; 584 case TerminalTokens.TokenNamereturn : 585 this.tagValue = TAG_RETURN_VALUE; 586 valid = parseReturn(); 587 595 break; 596 case TerminalTokens.TokenNamethrows : 597 this.tagValue = TAG_THROWS_VALUE; 598 valid = parseThrows(); 599 break; 600 } 601 this.textStart = this.index; 602 return valid; 603 } 604 605 608 protected boolean pushParamName(boolean isTypeParam) { 609 ASTNode nameRef = null; 611 if (isTypeParam) { 612 JavadocSingleTypeReference ref = new JavadocSingleTypeReference(this.identifierStack[1], 613 this.identifierPositionStack[1], 614 this.tagSourceStart, 615 this.tagSourceEnd); 616 nameRef = ref; 617 } else { 618 JavadocSingleNameReference ref = new JavadocSingleNameReference(this.identifierStack[0], 619 this.identifierPositionStack[0], 620 this.tagSourceStart, 621 this.tagSourceEnd); 622 nameRef = ref; 623 } 624 if (this.astLengthPtr == -1) { pushOnAstStack(nameRef, true); 627 } else { 628 if (!isTypeParam) { for (int i=THROWS_TAG_EXPECTED_ORDER; i<=this.astLengthPtr; i+=ORDERED_TAGS_NUMBER) { 631 if (this.astLengthStack[i] != 0) { 632 if (this.reportProblems) this.sourceParser.problemReporter().javadocUnexpectedTag(this.tagSourceStart, this.tagSourceEnd); 633 if (this.invalidParamReferencesPtr == -1l) { 636 this.invalidParamReferencesStack = new JavadocSingleNameReference[10]; 637 } 638 int stackLength = this.invalidParamReferencesStack.length; 639 if (++this.invalidParamReferencesPtr >= stackLength) { 640 System.arraycopy( 641 this.invalidParamReferencesStack, 0, 642 this.invalidParamReferencesStack = new JavadocSingleNameReference[stackLength + AST_STACK_INCREMENT], 0, 643 stackLength); 644 } 645 this.invalidParamReferencesStack[this.invalidParamReferencesPtr] = nameRef; 646 return false; 647 } 648 } 649 } 650 switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) { 651 case PARAM_TAG_EXPECTED_ORDER : 652 pushOnAstStack(nameRef, false); 654 break; 655 case SEE_TAG_EXPECTED_ORDER : 656 pushOnAstStack(nameRef, true); 658 break; 659 default: 660 return false; 661 } 662 } 663 return true; 664 } 665 666 669 protected boolean pushSeeRef(Object statement) { 670 if (this.astLengthPtr == -1) { pushOnAstStack(null, true); 672 pushOnAstStack(null, true); 673 pushOnAstStack(statement, true); 674 } else { 675 switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) { 676 case PARAM_TAG_EXPECTED_ORDER : 677 pushOnAstStack(null, true); 679 pushOnAstStack(statement, true); 680 break; 681 case THROWS_TAG_EXPECTED_ORDER : 682 pushOnAstStack(statement, true); 684 break; 685 case SEE_TAG_EXPECTED_ORDER : 686 pushOnAstStack(statement, false); 688 break; 689 default: 690 return false; 691 } 692 } 693 return true; 694 } 695 696 699 protected boolean pushThrowName(Object typeRef) { 700 if (this.astLengthPtr == -1) { pushOnAstStack(null, true); 702 pushOnAstStack(typeRef, true); 703 } else { 704 switch (this.astLengthPtr % ORDERED_TAGS_NUMBER) { 705 case PARAM_TAG_EXPECTED_ORDER : 706 pushOnAstStack(typeRef, true); 708 break; 709 case THROWS_TAG_EXPECTED_ORDER : 710 pushOnAstStack(typeRef, false); 712 break; 713 case SEE_TAG_EXPECTED_ORDER : 714 pushOnAstStack(null, true); 716 pushOnAstStack(typeRef, true); 717 break; 718 default: 719 return false; 720 } 721 } 722 return true; 723 } 724 725 728 protected void refreshReturnStatement() { 729 ((JavadocReturnStatement) this.returnStatement).bits &= ~ASTNode.Empty; 730 } 731 732 public String toString() { 733 StringBuffer buffer = new StringBuffer (); 734 buffer.append("check javadoc: ").append(this.checkDocComment).append("\n"); buffer.append("javadoc: ").append(this.docComment).append("\n"); buffer.append(super.toString()); 737 return buffer.toString(); 738 } 739 740 743 protected void updateDocComment() { 744 745 this.docComment.inheritedPositions = this.inheritedPositions; 747 this.docComment.valuePositions = this.validValuePositions != -1 ? this.validValuePositions : this.invalidValuePositions; 748 749 if (this.returnStatement != null) { 751 this.docComment.returnStatement = (JavadocReturnStatement) this.returnStatement; 752 } 753 754 if (this.invalidParamReferencesPtr >= 0) { 756 this.docComment.invalidParameters = new JavadocSingleNameReference[this.invalidParamReferencesPtr+1]; 757 System.arraycopy(this.invalidParamReferencesStack, 0, this.docComment.invalidParameters, 0, this.invalidParamReferencesPtr+1); 758 } 759 760 if (this.astLengthPtr == -1) { 762 return; 763 } 764 765 int[] sizes = new int[ORDERED_TAGS_NUMBER]; 767 for (int i=0; i<=this.astLengthPtr; i++) { 768 sizes[i%ORDERED_TAGS_NUMBER] += this.astLengthStack[i]; 769 } 770 this.docComment.seeReferences = new Expression[sizes[SEE_TAG_EXPECTED_ORDER]]; 771 this.docComment.exceptionReferences = new TypeReference[sizes[THROWS_TAG_EXPECTED_ORDER]]; 772 int paramRefPtr = sizes[PARAM_TAG_EXPECTED_ORDER]; 773 this.docComment.paramReferences = new JavadocSingleNameReference[paramRefPtr]; 774 int paramTypeParamPtr = sizes[PARAM_TAG_EXPECTED_ORDER]; 775 this.docComment.paramTypeParameters = new JavadocSingleTypeReference[paramTypeParamPtr]; 776 777 while (this.astLengthPtr >= 0) { 779 int ptr = this.astLengthPtr % ORDERED_TAGS_NUMBER; 780 switch(ptr) { 782 case SEE_TAG_EXPECTED_ORDER: 783 int size = this.astLengthStack[this.astLengthPtr--]; 784 for (int i=0; i<size; i++) { 785 this.docComment.seeReferences[--sizes[ptr]] = (Expression) this.astStack[this.astPtr--]; 786 } 787 break; 788 789 case THROWS_TAG_EXPECTED_ORDER: 791 size = this.astLengthStack[this.astLengthPtr--]; 792 for (int i=0; i<size; i++) { 793 this.docComment.exceptionReferences[--sizes[ptr]] = (TypeReference) this.astStack[this.astPtr--]; 794 } 795 break; 796 797 case PARAM_TAG_EXPECTED_ORDER: 799 size = this.astLengthStack[this.astLengthPtr--]; 800 for (int i=0; i<size; i++) { 801 Expression reference = (Expression) this.astStack[this.astPtr--]; 802 if (reference instanceof JavadocSingleNameReference) 803 this.docComment.paramReferences[--paramRefPtr] = (JavadocSingleNameReference) reference; 804 else if (reference instanceof JavadocSingleTypeReference) 805 this.docComment.paramTypeParameters[--paramTypeParamPtr] = (JavadocSingleTypeReference) reference; 806 } 807 break; 808 } 809 } 810 811 if (paramRefPtr == 0) { this.docComment.paramTypeParameters = null; 814 } else if (paramTypeParamPtr == 0) { this.docComment.paramReferences = null; 816 } else { int size = sizes[PARAM_TAG_EXPECTED_ORDER]; 818 System.arraycopy(this.docComment.paramReferences, paramRefPtr, this.docComment.paramReferences = new JavadocSingleNameReference[size - paramRefPtr], 0, size - paramRefPtr); 819 System.arraycopy(this.docComment.paramTypeParameters, paramTypeParamPtr, this.docComment.paramTypeParameters = new JavadocSingleTypeReference[size - paramTypeParamPtr], 0, size - paramTypeParamPtr); 820 } 821 } 822 } 823 | Popular Tags |