1 11 package org.eclipse.jdt.internal.compiler.ast; 12 13 import org.eclipse.jdt.core.compiler.CharOperation; 14 import org.eclipse.jdt.internal.compiler.ASTVisitor; 15 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 16 import org.eclipse.jdt.internal.compiler.lookup.*; 17 import org.eclipse.jdt.internal.compiler.parser.JavadocTagConstants; 18 19 22 public class Javadoc extends ASTNode { 23 24 public JavadocSingleNameReference[] paramReferences; public JavadocSingleTypeReference[] paramTypeParameters; public TypeReference[] exceptionReferences; public JavadocReturnStatement returnStatement; public Expression[] seeReferences; public long inheritedPositions = -1; 30 public JavadocSingleNameReference[] invalidParameters; public long valuePositions = -1; 36 37 public Javadoc(int sourceStart, int sourceEnd) { 38 this.sourceStart = sourceStart; 39 this.sourceEnd = sourceEnd; 40 } 41 48 boolean canBeSeen(int visibility, int modifiers) { 49 if (modifiers < 0) return true; 50 switch (modifiers & ExtraCompilerModifiers.AccVisibilityMASK) { 51 case ClassFileConstants.AccPublic : 52 return true; 53 case ClassFileConstants.AccProtected: 54 return (visibility != ClassFileConstants.AccPublic); 55 case ClassFileConstants.AccDefault: 56 return (visibility == ClassFileConstants.AccDefault || visibility == ClassFileConstants.AccPrivate); 57 case ClassFileConstants.AccPrivate: 58 return (visibility == ClassFileConstants.AccPrivate); 59 } 60 return true; 61 } 62 63 66 public ASTNode getNodeStartingAt(int start) { 67 int length = 0; 68 if (this.paramReferences != null) { 70 length = this.paramReferences.length; 71 for (int i=0; i<length; i++) { 72 JavadocSingleNameReference param = this.paramReferences[i]; 73 if (param.sourceStart==start) { 74 return param; 75 } 76 } 77 } 78 if (this.invalidParameters != null) { 80 length = this.invalidParameters.length; 81 for (int i=0; i<length; i++) { 82 JavadocSingleNameReference param = this.invalidParameters[i]; 83 if (param.sourceStart==start) { 84 return param; 85 } 86 } 87 } 88 if (this.paramTypeParameters != null) { 90 length = this.paramTypeParameters.length; 91 for (int i=0; i<length; i++) { 92 JavadocSingleTypeReference param = this.paramTypeParameters[i]; 93 if (param.sourceStart==start) { 94 return param; 95 } 96 } 97 } 98 if (this.exceptionReferences != null) { 100 length = this.exceptionReferences.length; 101 for (int i=0; i<length; i++) { 102 TypeReference typeRef = this.exceptionReferences[i]; 103 if (typeRef.sourceStart==start) { 104 return typeRef; 105 } 106 } 107 } 108 if (this.seeReferences != null) { 110 length = this.seeReferences.length; 111 for (int i=0; i<length; i++) { 112 org.eclipse.jdt.internal.compiler.ast.Expression expression = this.seeReferences[i]; 113 if (expression.sourceStart==start) { 114 return expression; 115 } else if (expression instanceof JavadocAllocationExpression) { 116 JavadocAllocationExpression allocationExpr = (JavadocAllocationExpression) this.seeReferences[i]; 117 if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) { 119 if (allocationExpr.arguments != null) { 120 for (int j=0, l=allocationExpr.arguments.length; j<l; j++) { 121 if (allocationExpr.arguments[j].sourceStart == start) { 122 return allocationExpr.arguments[j]; 123 } 124 } 125 } 126 } 127 } else if (expression instanceof JavadocMessageSend) { 128 JavadocMessageSend messageSend = (JavadocMessageSend) this.seeReferences[i]; 129 if (messageSend.binding != null && messageSend.binding.isValidBinding()) { 131 if (messageSend.arguments != null) { 132 for (int j=0, l=messageSend.arguments.length; j<l; j++) { 133 if (messageSend.arguments[j].sourceStart == start) { 134 return messageSend.arguments[j]; 135 } 136 } 137 } 138 } 139 } 140 } 141 } 142 return null; 143 } 144 145 148 public StringBuffer print(int indent, StringBuffer output) { 149 printIndent(indent, output).append("/**\n"); if (this.paramReferences != null) { 151 for (int i = 0, length = this.paramReferences.length; i < length; i++) { 152 printIndent(indent + 1, output).append(" * @param "); this.paramReferences[i].print(indent, output).append('\n'); 154 } 155 } 156 if (this.paramTypeParameters != null) { 157 for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) { 158 printIndent(indent + 1, output).append(" * @param <"); this.paramTypeParameters[i].print(indent, output).append(">\n"); } 161 } 162 if (this.returnStatement != null) { 163 printIndent(indent + 1, output).append(" * @"); this.returnStatement.print(indent, output).append('\n'); 165 } 166 if (this.exceptionReferences != null) { 167 for (int i = 0, length = this.exceptionReferences.length; i < length; i++) { 168 printIndent(indent + 1, output).append(" * @throws "); this.exceptionReferences[i].print(indent, output).append('\n'); 170 } 171 } 172 if (this.seeReferences != null) { 173 for (int i = 0, length = this.seeReferences.length; i < length; i++) { 174 printIndent(indent + 1, output).append(" * @see "); this.seeReferences[i].print(indent, output).append('\n'); 176 } 177 } 178 printIndent(indent, output).append(" */\n"); return output; 180 } 181 182 185 public void resolve(ClassScope scope) { 186 187 int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length; 189 for (int i = 0; i < paramTagsSize; i++) { 190 JavadocSingleNameReference param = this.paramReferences[i]; 191 scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd); 192 } 193 resolveTypeParameterTags(scope, true); 194 195 if (this.returnStatement != null) { 197 scope.problemReporter().javadocUnexpectedTag(this.returnStatement.sourceStart, this.returnStatement.sourceEnd); 198 } 199 200 int throwsTagsLength = this.exceptionReferences == null ? 0 : this.exceptionReferences.length; 202 for (int i = 0; i < throwsTagsLength; i++) { 203 TypeReference typeRef = this.exceptionReferences[i]; 204 int start, end; 205 if (typeRef instanceof JavadocSingleTypeReference) { 206 JavadocSingleTypeReference singleRef = (JavadocSingleTypeReference) typeRef; 207 start = singleRef.tagSourceStart; 208 end = singleRef.tagSourceEnd; 209 } else if (typeRef instanceof JavadocQualifiedTypeReference) { 210 JavadocQualifiedTypeReference qualifiedRef = (JavadocQualifiedTypeReference) typeRef; 211 start = qualifiedRef.tagSourceStart; 212 end = qualifiedRef.tagSourceEnd; 213 } else { 214 start = typeRef.sourceStart; 215 end = typeRef.sourceEnd; 216 } 217 scope.problemReporter().javadocUnexpectedTag(start, end); 218 } 219 220 int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length; 222 for (int i = 0; i < seeTagsLength; i++) { 223 resolveReference(this.seeReferences[i], scope); 224 } 225 226 boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 228 if (!source15 && this.valuePositions != -1) { 229 scope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions); 230 } 231 } 232 233 236 public void resolve(CompilationUnitScope unitScope) { 237 } 239 240 243 public void resolve(MethodScope methScope) { 244 245 AbstractMethodDeclaration methDecl = methScope.referenceMethod(); 247 boolean overriding = methDecl == null || methDecl.binding == null 248 ? false : 249 !methDecl.binding.isStatic() && ((methDecl.binding.modifiers & (ExtraCompilerModifiers.AccImplementing | ExtraCompilerModifiers.AccOverriding)) != 0); 250 251 int seeTagsLength = this.seeReferences == null ? 0 : this.seeReferences.length; 253 boolean superRef = false; 254 for (int i = 0; i < seeTagsLength; i++) { 255 256 resolveReference(this.seeReferences[i], methScope); 258 259 if (methDecl != null && (methDecl.isConstructor() || overriding) && !superRef) { 261 if (this.seeReferences[i] instanceof JavadocMessageSend) { 262 JavadocMessageSend messageSend = (JavadocMessageSend) this.seeReferences[i]; 263 if (messageSend.binding != null && messageSend.binding.isValidBinding() && messageSend.actualReceiverType instanceof ReferenceBinding) { 265 ReferenceBinding methodReceiverType = (ReferenceBinding) messageSend.actualReceiverType; 266 if ((methodReceiverType.isSuperclassOf(methDecl.binding.declaringClass) || (methodReceiverType.isInterface() && methDecl.binding.declaringClass.implementsInterface(methodReceiverType, true))) && 267 CharOperation.equals(messageSend.selector, methDecl.selector) && 268 (methDecl.binding.returnType.isCompatibleWith(messageSend.binding.returnType))) { 269 if (messageSend.arguments == null && methDecl.arguments == null) { 270 superRef = true; 271 } 272 else if (messageSend.arguments != null && methDecl.arguments != null) { 273 superRef = methDecl.binding.areParameterErasuresEqual(messageSend.binding); 274 } 275 } 276 } 277 } 278 else if (this.seeReferences[i] instanceof JavadocAllocationExpression) { 279 JavadocAllocationExpression allocationExpr = (JavadocAllocationExpression) this.seeReferences[i]; 280 if (allocationExpr.binding != null && allocationExpr.binding.isValidBinding()) { 282 if (methDecl.binding.declaringClass.isCompatibleWith(allocationExpr.resolvedType)) { 283 if (allocationExpr.arguments == null && methDecl.arguments == null) { 284 superRef = true; 285 } 286 else if (allocationExpr.arguments != null && methDecl.arguments != null && allocationExpr.arguments.length == methDecl.arguments.length) { 287 superRef = methDecl.binding.areParametersCompatibleWith(allocationExpr.binding.parameters); 288 } 289 } 290 } 291 } 292 } 293 } 294 295 if (!superRef && methDecl != null && methDecl.annotations != null) { 297 int length = methDecl.annotations.length; 298 for (int i=0; i<length && !superRef; i++) { 299 superRef = (methDecl.binding.tagBits & TagBits.AnnotationOverride) != 0; 300 } 301 } 302 303 boolean reportMissing = methDecl == null || !((overriding && this.inheritedPositions != -1) || superRef || (methDecl.binding.declaringClass != null && methDecl.binding.declaringClass.isLocalType())); 305 if (!overriding && this.inheritedPositions != -1) { 306 int start = (int) (this.inheritedPositions >>> 32); 307 int end = (int) this.inheritedPositions; 308 methScope.problemReporter().javadocUnexpectedTag(start, end); 309 } 310 311 boolean considerParamRefAsUsage = methScope.compilerOptions().reportUnusedParameterIncludeDocCommentReference; 313 resolveParamTags(methScope, reportMissing, considerParamRefAsUsage); 314 resolveTypeParameterTags(methScope, reportMissing); 315 316 if (this.returnStatement == null) { 318 if (reportMissing && methDecl != null) { 319 if (methDecl.isMethod()) { 320 MethodDeclaration meth = (MethodDeclaration) methDecl; 321 if (meth.binding.returnType != TypeBinding.VOID) { 322 methScope.problemReporter().javadocMissingReturnTag(meth.returnType.sourceStart, meth.returnType.sourceEnd, methDecl.binding.modifiers); 324 } 325 } 326 } 327 } else { 328 this.returnStatement.resolve(methScope); 329 } 330 331 resolveThrowsTags(methScope, reportMissing); 333 334 boolean source15 = methScope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 336 if (!source15 && methDecl != null && this.valuePositions != -1) { 337 methScope.problemReporter().javadocUnexpectedTag((int)(this.valuePositions>>>32), (int) this.valuePositions); 338 } 339 340 int length = this.invalidParameters == null ? 0 : this.invalidParameters.length; 342 for (int i = 0; i < length; i++) { 343 this.invalidParameters[i].resolve(methScope, false, false); 344 } 345 } 346 347 private void resolveReference(Expression reference, Scope scope) { 348 349 int problemCount = scope.referenceContext().compilationResult().problemCount; 351 switch (scope.kind) { 352 case Scope.METHOD_SCOPE: 353 reference.resolveType((MethodScope)scope); 354 break; 355 case Scope.CLASS_SCOPE: 356 reference.resolveType((ClassScope)scope); 357 break; 358 } 359 boolean hasProblems = scope.referenceContext().compilationResult().problemCount > problemCount; 360 361 boolean source15 = scope.compilerOptions().sourceLevel >= ClassFileConstants.JDK1_5; 363 int scopeModifiers = -1; 364 if (reference instanceof JavadocFieldReference) { 365 JavadocFieldReference fieldRef = (JavadocFieldReference) reference; 366 367 if (fieldRef.methodBinding != null) { 370 if (fieldRef.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { 372 if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); 373 scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers); 374 } 375 else if (fieldRef.receiverType != null) { 376 if (scope.enclosingSourceType().isCompatibleWith(fieldRef.receiverType)) { 377 fieldRef.bits |= ASTNode.SuperAccess; 378 } 379 fieldRef.methodBinding = scope.findMethod((ReferenceBinding)fieldRef.receiverType, fieldRef.token, new TypeBinding[0], fieldRef); 380 } 381 } 382 383 else if (source15 && fieldRef.binding != null && fieldRef.binding.isValidBinding()) { 385 if (fieldRef.tagValue == JavadocTagConstants.TAG_VALUE_VALUE && !fieldRef.binding.isStatic()) { 386 if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); 387 scope.problemReporter().javadocInvalidValueReference(fieldRef.sourceStart, fieldRef.sourceEnd, scopeModifiers); 388 } 389 } 390 391 if (!hasProblems && fieldRef.binding != null && fieldRef.binding.isValidBinding() && fieldRef.receiverType instanceof ReferenceBinding) { 393 ReferenceBinding resolvedType = (ReferenceBinding) fieldRef.receiverType; 394 verifyTypeReference(fieldRef, fieldRef.receiver, scope, source15, resolvedType, fieldRef.binding.modifiers); 395 } 396 397 return; 399 } 400 401 if (!hasProblems && (reference instanceof JavadocSingleTypeReference || reference instanceof JavadocQualifiedTypeReference) && reference.resolvedType instanceof ReferenceBinding) { 403 ReferenceBinding resolvedType = (ReferenceBinding) reference.resolvedType; 404 verifyTypeReference(reference, reference, scope, source15, resolvedType, resolvedType.modifiers); 405 } 406 407 if (reference instanceof JavadocMessageSend) { 409 JavadocMessageSend msgSend = (JavadocMessageSend) reference; 410 411 if (source15 && msgSend.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); 414 scope.problemReporter().javadocInvalidValueReference(msgSend.sourceStart, msgSend.sourceEnd, scopeModifiers); 415 } 416 417 if (!hasProblems && msgSend.binding != null && msgSend.binding.isValidBinding() && msgSend.actualReceiverType instanceof ReferenceBinding) { 419 ReferenceBinding resolvedType = (ReferenceBinding) msgSend.actualReceiverType; 420 verifyTypeReference(msgSend, msgSend.receiver, scope, source15, resolvedType, msgSend.binding.modifiers); 421 } 422 } 423 424 else if (reference instanceof JavadocAllocationExpression) { 426 JavadocAllocationExpression alloc = (JavadocAllocationExpression) reference; 427 428 if (source15 && alloc.tagValue == JavadocTagConstants.TAG_VALUE_VALUE) { if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); 431 scope.problemReporter().javadocInvalidValueReference(alloc.sourceStart, alloc.sourceEnd, scopeModifiers); 432 } 433 434 if (!hasProblems && alloc.binding != null && alloc.binding.isValidBinding() && alloc.resolvedType instanceof ReferenceBinding) { 436 ReferenceBinding resolvedType = (ReferenceBinding) alloc.resolvedType; 437 verifyTypeReference(alloc, alloc.type, scope, source15, resolvedType, alloc.binding.modifiers); 438 } 439 } 440 441 if (reference.resolvedType != null && reference.resolvedType.isTypeVariable()) { 444 scope.problemReporter().javadocInvalidReference(reference.sourceStart, reference.sourceEnd); 445 } 446 } 447 448 451 private void resolveParamTags(MethodScope scope, boolean reportMissing, boolean considerParamRefAsUsage) { 452 AbstractMethodDeclaration methodDecl = scope.referenceMethod(); 453 int paramTagsSize = this.paramReferences == null ? 0 : this.paramReferences.length; 454 455 if (methodDecl == null) { 457 for (int i = 0; i < paramTagsSize; i++) { 458 JavadocSingleNameReference param = this.paramReferences[i]; 459 scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd); 460 } 461 return; 462 } 463 464 int argumentsSize = methodDecl.arguments == null ? 0 : methodDecl.arguments.length; 466 if (paramTagsSize == 0) { 467 if (reportMissing) { 468 for (int i = 0; i < argumentsSize; i++) { 469 Argument arg = methodDecl.arguments[i]; 470 scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, methodDecl.binding.modifiers); 471 } 472 } 473 } else { 474 LocalVariableBinding[] bindings = new LocalVariableBinding[paramTagsSize]; 475 int maxBindings = 0; 476 477 for (int i = 0; i < paramTagsSize; i++) { 479 JavadocSingleNameReference param = this.paramReferences[i]; 480 param.resolve(scope, true, considerParamRefAsUsage); 481 if (param.binding != null && param.binding.isValidBinding()) { 482 boolean found = false; 484 for (int j = 0; j < maxBindings && !found; j++) { 485 if (bindings[j] == param.binding) { 486 scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, methodDecl.binding.modifiers); 487 found = true; 488 } 489 } 490 if (!found) { 491 bindings[maxBindings++] = (LocalVariableBinding) param.binding; 492 } 493 } 494 } 495 496 if (reportMissing) { 498 for (int i = 0; i < argumentsSize; i++) { 499 Argument arg = methodDecl.arguments[i]; 500 boolean found = false; 501 for (int j = 0; j < maxBindings && !found; j++) { 502 LocalVariableBinding binding = bindings[j]; 503 if (arg.binding == binding) { 504 found = true; 505 } 506 } 507 if (!found) { 508 scope.problemReporter().javadocMissingParamTag(arg.name, arg.sourceStart, arg.sourceEnd, methodDecl.binding.modifiers); 509 } 510 } 511 } 512 } 513 } 514 515 518 private void resolveTypeParameterTags(Scope scope, boolean reportMissing) { 519 int paramTypeParamLength = this.paramTypeParameters == null ? 0 : this.paramTypeParameters.length; 520 521 TypeParameter[] parameters = null; 523 TypeVariableBinding[] typeVariables = null; 524 int modifiers = -1; 525 switch (scope.kind) { 526 case Scope.METHOD_SCOPE: 527 AbstractMethodDeclaration methodDeclaration = ((MethodScope)scope).referenceMethod(); 528 if (methodDeclaration == null) { 530 for (int i = 0; i < paramTypeParamLength; i++) { 531 JavadocSingleNameReference param = this.paramReferences[i]; 532 scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd); 533 } 534 return; 535 } 536 parameters = methodDeclaration.typeParameters(); 537 typeVariables = methodDeclaration.binding.typeVariables; 538 modifiers = methodDeclaration.binding.modifiers; 539 break; 540 case Scope.CLASS_SCOPE: 541 TypeDeclaration typeDeclaration = ((ClassScope) scope).referenceContext; 542 parameters = typeDeclaration.typeParameters; 543 typeVariables = typeDeclaration.binding.typeVariables; 544 modifiers = typeDeclaration.binding.modifiers; 545 break; 546 } 547 548 if (typeVariables == null || typeVariables.length == 0) { 550 for (int i = 0; i < paramTypeParamLength; i++) { 551 JavadocSingleTypeReference param = this.paramTypeParameters[i]; 552 scope.problemReporter().javadocUnexpectedTag(param.tagSourceStart, param.tagSourceEnd); 553 } 554 return; 555 } 556 557 if (parameters != null) { 559 int typeParametersLength = parameters.length; 560 if (paramTypeParamLength == 0) { 561 if (reportMissing) { 562 for (int i = 0, l=typeParametersLength; i<l; i++) { 563 scope.problemReporter().javadocMissingParamTag(parameters[i].name, parameters[i].sourceStart, parameters[i].sourceEnd, modifiers); 564 } 565 } 566 567 } else if (typeVariables.length == typeParametersLength) { 569 TypeVariableBinding[] bindings = new TypeVariableBinding[paramTypeParamLength]; 570 571 for (int i = 0; i < paramTypeParamLength; i++) { 573 JavadocSingleTypeReference param = this.paramTypeParameters[i]; 574 TypeBinding paramBindind = param.internalResolveType(scope); 575 if (paramBindind != null && paramBindind.isValidBinding()) { 576 if (paramBindind.isTypeVariable()) { 577 boolean duplicate = false; 579 for (int j = 0; j < i && !duplicate; j++) { 580 if (bindings[j] == param.resolvedType) { 581 scope.problemReporter().javadocDuplicatedParamTag(param.token, param.sourceStart, param.sourceEnd, modifiers); 582 duplicate = true; 583 } 584 } 585 if (!duplicate) { 586 bindings[i] = (TypeVariableBinding) param.resolvedType; 587 } 588 } else { 589 scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers); 590 } 591 } 592 } 593 594 for (int i = 0; i < typeParametersLength; i++) { 596 TypeParameter parameter = parameters[i]; 597 boolean found = false; 598 for (int j = 0; j < paramTypeParamLength && !found; j++) { 599 if (parameter.binding == bindings[j]) { 600 found = true; 601 bindings[j] = null; 602 } 603 } 604 if (!found && reportMissing) { 605 scope.problemReporter().javadocMissingParamTag(parameter.name, parameter.sourceStart, parameter.sourceEnd, modifiers); 606 } 607 } 608 609 for (int i=0; i<paramTypeParamLength; i++) { 611 if (bindings[i] != null) { 612 JavadocSingleTypeReference param = this.paramTypeParameters[i]; 613 scope.problemReporter().javadocUndeclaredParamTagName(param.token, param.sourceStart, param.sourceEnd, modifiers); 614 } 615 } 616 } 617 } 618 } 619 620 623 private void resolveThrowsTags(MethodScope methScope, boolean reportMissing) { 624 AbstractMethodDeclaration md = methScope.referenceMethod(); 625 int throwsTagsLength = this.exceptionReferences == null ? 0 : this.exceptionReferences.length; 626 627 if (md == null) { 629 for (int i = 0; i < throwsTagsLength; i++) { 630 TypeReference typeRef = this.exceptionReferences[i]; 631 int start = typeRef.sourceStart; 632 int end = typeRef.sourceEnd; 633 if (typeRef instanceof JavadocQualifiedTypeReference) { 634 start = ((JavadocQualifiedTypeReference) typeRef).tagSourceStart; 635 end = ((JavadocQualifiedTypeReference) typeRef).tagSourceEnd; 636 } else if (typeRef instanceof JavadocSingleTypeReference) { 637 start = ((JavadocSingleTypeReference) typeRef).tagSourceStart; 638 end = ((JavadocSingleTypeReference) typeRef).tagSourceEnd; 639 } 640 methScope.problemReporter().javadocUnexpectedTag(start, end); 641 } 642 return; 643 } 644 645 int boundExceptionLength = (md.binding == null) ? 0 : md.binding.thrownExceptions.length; 647 int thrownExceptionLength = md.thrownExceptions == null ? 0 : md.thrownExceptions.length; 648 if (throwsTagsLength == 0) { 649 if (reportMissing) { 650 for (int i = 0; i < boundExceptionLength; i++) { 651 ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i]; 652 if (exceptionBinding != null && exceptionBinding.isValidBinding()) { int j=i; 654 while (j<thrownExceptionLength && exceptionBinding != md.thrownExceptions[j].resolvedType) j++; 655 if (j<thrownExceptionLength) { 656 methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[j], md.binding.modifiers); 657 } 658 } 659 } 660 } 661 } else { 662 int maxRef = 0; 663 TypeReference[] typeReferences = new TypeReference[throwsTagsLength]; 664 665 for (int i = 0; i < throwsTagsLength; i++) { 667 TypeReference typeRef = this.exceptionReferences[i]; 668 typeRef.resolve(methScope); 669 TypeBinding typeBinding = typeRef.resolvedType; 670 671 if (typeBinding != null && typeBinding.isValidBinding() && typeBinding.isClass()) { 672 typeReferences[maxRef++] = typeRef; 674 } 675 } 676 677 for (int i = 0; i < boundExceptionLength; i++) { 679 ReferenceBinding exceptionBinding = md.binding.thrownExceptions[i]; 680 if (exceptionBinding != null) exceptionBinding = (ReferenceBinding) exceptionBinding.erasure(); 681 boolean found = false; 682 for (int j = 0; j < maxRef && !found; j++) { 683 if (typeReferences[j] != null) { 684 TypeBinding typeBinding = typeReferences[j].resolvedType; 685 if (exceptionBinding == typeBinding) { 686 found = true; 687 typeReferences[j] = null; 688 } 689 } 690 } 691 if (!found && reportMissing) { 692 if (exceptionBinding != null && exceptionBinding.isValidBinding()) { int k=i; 694 while (k<thrownExceptionLength && exceptionBinding != md.thrownExceptions[k].resolvedType) k++; 695 if (k<thrownExceptionLength) { 696 methScope.problemReporter().javadocMissingThrowsTag(md.thrownExceptions[k], md.binding.modifiers); 697 } 698 } 699 } 700 } 701 702 for (int i = 0; i < maxRef; i++) { 704 TypeReference typeRef = typeReferences[i]; 705 if (typeRef != null) { 706 boolean compatible = false; 707 for (int j = 0; j<thrownExceptionLength && !compatible; j++) { 709 TypeBinding exceptionBinding = md.thrownExceptions[j].resolvedType; 710 if (exceptionBinding != null) { 711 compatible = typeRef.resolvedType.isCompatibleWith(exceptionBinding); 712 } 713 } 714 715 if (!compatible && !typeRef.resolvedType.isUncheckedException(false)) { 717 methScope.problemReporter().javadocInvalidThrowsClassName(typeRef, md.binding.modifiers); 718 } 719 } 720 } 721 } 722 } 723 724 private void verifyTypeReference(Expression reference, Expression typeReference, Scope scope, boolean source15, ReferenceBinding resolvedType, int modifiers) { 725 if (resolvedType.isValidBinding()) { 726 int scopeModifiers = -1; 727 728 if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, modifiers)) { 730 scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, reference.sourceEnd, scope, modifiers); 731 return; 732 } 733 734 if (reference != typeReference) { 736 if (!canBeSeen(scope.problemReporter().options.reportInvalidJavadocTagsVisibility, resolvedType.modifiers)) { 737 scope.problemReporter().javadocHiddenReference(typeReference.sourceStart, typeReference.sourceEnd, scope, resolvedType.modifiers); 738 return; 739 } 740 } 741 742 if (resolvedType.isMemberType()) { 744 ReferenceBinding topLevelType = resolvedType; 745 int packageLength = topLevelType.fPackage.compoundName.length; 747 int depth = resolvedType.depth(); 748 int idx = depth + packageLength; 749 char[][] computedCompoundName = new char[idx+1][]; 750 computedCompoundName[idx] = topLevelType.sourceName; 751 while (topLevelType.enclosingType() != null) { 752 topLevelType = topLevelType.enclosingType(); 753 computedCompoundName[--idx] = topLevelType.sourceName; 754 } 755 756 for (int i = packageLength; --i >= 0;) { 758 computedCompoundName[--idx] = topLevelType.fPackage.compoundName[i]; 759 } 760 761 ClassScope topLevelScope = scope.classScope(); 762 if (topLevelScope.parent.kind != Scope.COMPILATION_UNIT_SCOPE || 764 !CharOperation.equals(topLevelType.sourceName, topLevelScope.referenceContext.name)) { 765 topLevelScope = topLevelScope.outerMostClassScope(); 766 if (typeReference instanceof JavadocSingleTypeReference) { 767 if ((!source15 && depth == 1) || topLevelType != topLevelScope.referenceContext.binding) { 769 boolean hasValidImport = false; 771 if (source15) { 772 CompilationUnitScope unitScope = topLevelScope.compilationUnitScope(); 773 ImportBinding[] imports = unitScope.imports; 774 int length = imports == null ? 0 : imports.length; 775 mainLoop: for (int i=0; i<length; i++) { 776 char[][] compoundName = imports[i].compoundName; 777 int compoundNameLength = compoundName.length; 778 if ((imports[i].onDemand && compoundNameLength == computedCompoundName.length-1) || 779 (compoundNameLength == computedCompoundName.length)) 780 { 781 for (int j = compoundNameLength; --j >= 0;) { 782 if (CharOperation.equals(imports[i].compoundName[j], computedCompoundName[j])) { 783 if (j == 0) { 784 hasValidImport = true; 785 break mainLoop; 786 } 787 } else { 788 break; 789 } 790 } 791 } 792 } 793 if (!hasValidImport) { 794 if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); 795 scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers); 796 } 797 } else { 798 if (scopeModifiers == -1) scopeModifiers = scope.getDeclarationModifiers(); 799 scope.problemReporter().javadocInvalidMemberTypeQualification(typeReference.sourceStart, typeReference.sourceEnd, scopeModifiers); 800 return; 801 } 802 } 803 } 804 } 805 } 806 } 807 } 808 809 public void traverse(ASTVisitor visitor, BlockScope scope) { 810 if (visitor.visit(this, scope)) { 811 if (this.paramReferences != null) { 812 for (int i = 0, length = this.paramReferences.length; i < length; i++) { 813 this.paramReferences[i].traverse(visitor, scope); 814 } 815 } 816 if (this.paramTypeParameters != null) { 817 for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) { 818 this.paramTypeParameters[i].traverse(visitor, scope); 819 } 820 } 821 if (this.returnStatement != null) { 822 this.returnStatement.traverse(visitor, scope); 823 } 824 if (this.exceptionReferences != null) { 825 for (int i = 0, length = this.exceptionReferences.length; i < length; i++) { 826 this.exceptionReferences[i].traverse(visitor, scope); 827 } 828 } 829 if (this.seeReferences != null) { 830 for (int i = 0, length = this.seeReferences.length; i < length; i++) { 831 this.seeReferences[i].traverse(visitor, scope); 832 } 833 } 834 } 835 visitor.endVisit(this, scope); 836 } 837 public void traverse(ASTVisitor visitor, ClassScope scope) { 838 if (visitor.visit(this, scope)) { 839 if (this.paramReferences != null) { 840 for (int i = 0, length = this.paramReferences.length; i < length; i++) { 841 this.paramReferences[i].traverse(visitor, scope); 842 } 843 } 844 if (this.paramTypeParameters != null) { 845 for (int i = 0, length = this.paramTypeParameters.length; i < length; i++) { 846 this.paramTypeParameters[i].traverse(visitor, scope); 847 } 848 } 849 if (this.returnStatement != null) { 850 this.returnStatement.traverse(visitor, scope); 851 } 852 if (this.exceptionReferences != null) { 853 for (int i = 0, length = this.exceptionReferences.length; i < length; i++) { 854 this.exceptionReferences[i].traverse(visitor, scope); 855 } 856 } 857 if (this.seeReferences != null) { 858 for (int i = 0, length = this.seeReferences.length; i < length; i++) { 859 this.seeReferences[i].traverse(visitor, scope); 860 } 861 } 862 } 863 visitor.endVisit(this, scope); 864 } 865 } 866 | Popular Tags |