langtools/src/jdk.compiler/share/classes/com/sun/tools/doclint/Checker.java
changeset 26266 2d24bda701dc
parent 25874 83c19f00452c
child 29291 076c277565f7
equal deleted inserted replaced
26265:46aacfffd3b5 26266:2d24bda701dc
    79 import com.sun.source.util.DocTreePath;
    79 import com.sun.source.util.DocTreePath;
    80 import com.sun.source.util.DocTreePathScanner;
    80 import com.sun.source.util.DocTreePathScanner;
    81 import com.sun.source.util.TreePath;
    81 import com.sun.source.util.TreePath;
    82 import com.sun.tools.doclint.HtmlTag.AttrKind;
    82 import com.sun.tools.doclint.HtmlTag.AttrKind;
    83 import com.sun.tools.javac.tree.DocPretty;
    83 import com.sun.tools.javac.tree.DocPretty;
       
    84 import com.sun.tools.javac.util.DefinedBy;
       
    85 import com.sun.tools.javac.util.DefinedBy.Api;
    84 import com.sun.tools.javac.util.StringUtils;
    86 import com.sun.tools.javac.util.StringUtils;
    85 import static com.sun.tools.doclint.Messages.Group.*;
    87 import static com.sun.tools.doclint.Messages.Group.*;
    86 
    88 
    87 
    89 
    88 /**
    90 /**
   211 
   213 
   212     private void reportReference(String code, Object... args) {
   214     private void reportReference(String code, Object... args) {
   213         env.messages.report(REFERENCE, Kind.WARNING, env.currPath.getLeaf(), code, args);
   215         env.messages.report(REFERENCE, Kind.WARNING, env.currPath.getLeaf(), code, args);
   214     }
   216     }
   215 
   217 
   216     @Override
   218     @Override @DefinedBy(Api.COMPILER_TREE)
   217     public Void visitDocComment(DocCommentTree tree, Void ignore) {
   219     public Void visitDocComment(DocCommentTree tree, Void ignore) {
   218         super.visitDocComment(tree, ignore);
   220         super.visitDocComment(tree, ignore);
   219         for (TagStackItem tsi: tagStack) {
   221         for (TagStackItem tsi: tagStack) {
   220             warnIfEmpty(tsi, null);
   222             warnIfEmpty(tsi, null);
   221             if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT
   223             if (tsi.tree.getKind() == DocTree.Kind.START_ELEMENT
   228     }
   230     }
   229     // </editor-fold>
   231     // </editor-fold>
   230 
   232 
   231     // <editor-fold defaultstate="collapsed" desc="Text and entities.">
   233     // <editor-fold defaultstate="collapsed" desc="Text and entities.">
   232 
   234 
   233     @Override
   235     @Override @DefinedBy(Api.COMPILER_TREE)
   234     public Void visitText(TextTree tree, Void ignore) {
   236     public Void visitText(TextTree tree, Void ignore) {
   235         if (hasNonWhitespace(tree)) {
   237         if (hasNonWhitespace(tree)) {
   236             checkAllowsText(tree);
   238             checkAllowsText(tree);
   237             markEnclosingTag(Flag.HAS_TEXT);
   239             markEnclosingTag(Flag.HAS_TEXT);
   238         }
   240         }
   239         return null;
   241         return null;
   240     }
   242     }
   241 
   243 
   242     @Override
   244     @Override @DefinedBy(Api.COMPILER_TREE)
   243     public Void visitEntity(EntityTree tree, Void ignore) {
   245     public Void visitEntity(EntityTree tree, Void ignore) {
   244         checkAllowsText(tree);
   246         checkAllowsText(tree);
   245         markEnclosingTag(Flag.HAS_TEXT);
   247         markEnclosingTag(Flag.HAS_TEXT);
   246         String name = tree.getName().toString();
   248         String name = tree.getName().toString();
   247         if (name.startsWith("#")) {
   249         if (name.startsWith("#")) {
   271 
   273 
   272     // </editor-fold>
   274     // </editor-fold>
   273 
   275 
   274     // <editor-fold defaultstate="collapsed" desc="HTML elements">
   276     // <editor-fold defaultstate="collapsed" desc="HTML elements">
   275 
   277 
   276     @Override
   278     @Override @DefinedBy(Api.COMPILER_TREE)
   277     public Void visitStartElement(StartElementTree tree, Void ignore) {
   279     public Void visitStartElement(StartElementTree tree, Void ignore) {
   278         final Name treeName = tree.getName();
   280         final Name treeName = tree.getName();
   279         final HtmlTag t = HtmlTag.get(treeName);
   281         final HtmlTag t = HtmlTag.get(treeName);
   280         if (t == null) {
   282         if (t == null) {
   281             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
   283             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
   435             case H6: return 6;
   437             case H6: return 6;
   436             default: throw new IllegalArgumentException();
   438             default: throw new IllegalArgumentException();
   437         }
   439         }
   438     }
   440     }
   439 
   441 
   440     @Override
   442     @Override @DefinedBy(Api.COMPILER_TREE)
   441     public Void visitEndElement(EndElementTree tree, Void ignore) {
   443     public Void visitEndElement(EndElementTree tree, Void ignore) {
   442         final Name treeName = tree.getName();
   444         final Name treeName = tree.getName();
   443         final HtmlTag t = HtmlTag.get(treeName);
   445         final HtmlTag t = HtmlTag.get(treeName);
   444         if (t == null) {
   446         if (t == null) {
   445             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
   447             env.messages.error(HTML, tree, "dc.tag.unknown", treeName);
   507 
   509 
   508     // </editor-fold>
   510     // </editor-fold>
   509 
   511 
   510     // <editor-fold defaultstate="collapsed" desc="HTML attributes">
   512     // <editor-fold defaultstate="collapsed" desc="HTML attributes">
   511 
   513 
   512     @Override @SuppressWarnings("fallthrough")
   514     @Override @DefinedBy(Api.COMPILER_TREE) @SuppressWarnings("fallthrough")
   513     public Void visitAttribute(AttributeTree tree, Void ignore) {
   515     public Void visitAttribute(AttributeTree tree, Void ignore) {
   514         HtmlTag currTag = tagStack.peek().tag;
   516         HtmlTag currTag = tagStack.peek().tag;
   515         if (currTag != null) {
   517         if (currTag != null) {
   516             Name name = tree.getName();
   518             Name name = tree.getName();
   517             HtmlTag.Attr attr = currTag.getAttr(name);
   519             HtmlTag.Attr attr = currTag.getAttr(name);
   652     }
   654     }
   653     // </editor-fold>
   655     // </editor-fold>
   654 
   656 
   655     // <editor-fold defaultstate="collapsed" desc="javadoc tags">
   657     // <editor-fold defaultstate="collapsed" desc="javadoc tags">
   656 
   658 
   657     @Override
   659     @Override @DefinedBy(Api.COMPILER_TREE)
   658     public Void visitAuthor(AuthorTree tree, Void ignore) {
   660     public Void visitAuthor(AuthorTree tree, Void ignore) {
   659         warnIfEmpty(tree, tree.getName());
   661         warnIfEmpty(tree, tree.getName());
   660         return super.visitAuthor(tree, ignore);
   662         return super.visitAuthor(tree, ignore);
   661     }
   663     }
   662 
   664 
   663     @Override
   665     @Override @DefinedBy(Api.COMPILER_TREE)
   664     public Void visitDocRoot(DocRootTree tree, Void ignore) {
   666     public Void visitDocRoot(DocRootTree tree, Void ignore) {
   665         markEnclosingTag(Flag.HAS_INLINE_TAG);
   667         markEnclosingTag(Flag.HAS_INLINE_TAG);
   666         return super.visitDocRoot(tree, ignore);
   668         return super.visitDocRoot(tree, ignore);
   667     }
   669     }
   668 
   670 
   669     @Override
   671     @Override @DefinedBy(Api.COMPILER_TREE)
   670     public Void visitInheritDoc(InheritDocTree tree, Void ignore) {
   672     public Void visitInheritDoc(InheritDocTree tree, Void ignore) {
   671         markEnclosingTag(Flag.HAS_INLINE_TAG);
   673         markEnclosingTag(Flag.HAS_INLINE_TAG);
   672         // TODO: verify on overridden method
   674         // TODO: verify on overridden method
   673         foundInheritDoc = true;
   675         foundInheritDoc = true;
   674         return super.visitInheritDoc(tree, ignore);
   676         return super.visitInheritDoc(tree, ignore);
   675     }
   677     }
   676 
   678 
   677     @Override
   679     @Override @DefinedBy(Api.COMPILER_TREE)
   678     public Void visitLink(LinkTree tree, Void ignore) {
   680     public Void visitLink(LinkTree tree, Void ignore) {
   679         markEnclosingTag(Flag.HAS_INLINE_TAG);
   681         markEnclosingTag(Flag.HAS_INLINE_TAG);
   680         // simulate inline context on tag stack
   682         // simulate inline context on tag stack
   681         HtmlTag t = (tree.getKind() == DocTree.Kind.LINK)
   683         HtmlTag t = (tree.getKind() == DocTree.Kind.LINK)
   682                 ? HtmlTag.CODE : HtmlTag.SPAN;
   684                 ? HtmlTag.CODE : HtmlTag.SPAN;
   686         } finally {
   688         } finally {
   687             tagStack.pop();
   689             tagStack.pop();
   688         }
   690         }
   689     }
   691     }
   690 
   692 
   691     @Override
   693     @Override @DefinedBy(Api.COMPILER_TREE)
   692     public Void visitLiteral(LiteralTree tree, Void ignore) {
   694     public Void visitLiteral(LiteralTree tree, Void ignore) {
   693         markEnclosingTag(Flag.HAS_INLINE_TAG);
   695         markEnclosingTag(Flag.HAS_INLINE_TAG);
   694         if (tree.getKind() == DocTree.Kind.CODE) {
   696         if (tree.getKind() == DocTree.Kind.CODE) {
   695             for (TagStackItem tsi: tagStack) {
   697             for (TagStackItem tsi: tagStack) {
   696                 if (tsi.tag == HtmlTag.CODE) {
   698                 if (tsi.tag == HtmlTag.CODE) {
   700             }
   702             }
   701         }
   703         }
   702         return super.visitLiteral(tree, ignore);
   704         return super.visitLiteral(tree, ignore);
   703     }
   705     }
   704 
   706 
   705     @Override
   707     @Override @DefinedBy(Api.COMPILER_TREE)
   706     @SuppressWarnings("fallthrough")
   708     @SuppressWarnings("fallthrough")
   707     public Void visitParam(ParamTree tree, Void ignore) {
   709     public Void visitParam(ParamTree tree, Void ignore) {
   708         boolean typaram = tree.isTypeParameter();
   710         boolean typaram = tree.isTypeParameter();
   709         IdentifierTree nameTree = tree.getName();
   711         IdentifierTree nameTree = tree.getName();
   710         Element paramElement = nameTree != null ? env.trees.getElement(new DocTreePath(getCurrentPath(), nameTree)) : null;
   712         Element paramElement = nameTree != null ? env.trees.getElement(new DocTreePath(getCurrentPath(), nameTree)) : null;
   746                 reportMissing("dc.missing.param", paramName);
   748                 reportMissing("dc.missing.param", paramName);
   747             }
   749             }
   748         }
   750         }
   749     }
   751     }
   750 
   752 
   751     @Override
   753     @Override @DefinedBy(Api.COMPILER_TREE)
   752     public Void visitReference(ReferenceTree tree, Void ignore) {
   754     public Void visitReference(ReferenceTree tree, Void ignore) {
   753         String sig = tree.getSignature();
   755         String sig = tree.getSignature();
   754         if (sig.contains("<") || sig.contains(">"))
   756         if (sig.contains("<") || sig.contains(">"))
   755             env.messages.error(REFERENCE, tree, "dc.type.arg.not.allowed");
   757             env.messages.error(REFERENCE, tree, "dc.type.arg.not.allowed");
   756 
   758 
   758         if (e == null)
   760         if (e == null)
   759             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
   761             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
   760         return super.visitReference(tree, ignore);
   762         return super.visitReference(tree, ignore);
   761     }
   763     }
   762 
   764 
   763     @Override
   765     @Override @DefinedBy(Api.COMPILER_TREE)
   764     public Void visitReturn(ReturnTree tree, Void ignore) {
   766     public Void visitReturn(ReturnTree tree, Void ignore) {
   765         Element e = env.trees.getElement(env.currPath);
   767         Element e = env.trees.getElement(env.currPath);
   766         if (e.getKind() != ElementKind.METHOD
   768         if (e.getKind() != ElementKind.METHOD
   767                 || ((ExecutableElement) e).getReturnType().getKind() == TypeKind.VOID)
   769                 || ((ExecutableElement) e).getReturnType().getKind() == TypeKind.VOID)
   768             env.messages.error(REFERENCE, tree, "dc.invalid.return");
   770             env.messages.error(REFERENCE, tree, "dc.invalid.return");
   769         foundReturn = true;
   771         foundReturn = true;
   770         warnIfEmpty(tree, tree.getDescription());
   772         warnIfEmpty(tree, tree.getDescription());
   771         return super.visitReturn(tree, ignore);
   773         return super.visitReturn(tree, ignore);
   772     }
   774     }
   773 
   775 
   774     @Override
   776     @Override @DefinedBy(Api.COMPILER_TREE)
   775     public Void visitSerialData(SerialDataTree tree, Void ignore) {
   777     public Void visitSerialData(SerialDataTree tree, Void ignore) {
   776         warnIfEmpty(tree, tree.getDescription());
   778         warnIfEmpty(tree, tree.getDescription());
   777         return super.visitSerialData(tree, ignore);
   779         return super.visitSerialData(tree, ignore);
   778     }
   780     }
   779 
   781 
   780     @Override
   782     @Override @DefinedBy(Api.COMPILER_TREE)
   781     public Void visitSerialField(SerialFieldTree tree, Void ignore) {
   783     public Void visitSerialField(SerialFieldTree tree, Void ignore) {
   782         warnIfEmpty(tree, tree.getDescription());
   784         warnIfEmpty(tree, tree.getDescription());
   783         return super.visitSerialField(tree, ignore);
   785         return super.visitSerialField(tree, ignore);
   784     }
   786     }
   785 
   787 
   786     @Override
   788     @Override @DefinedBy(Api.COMPILER_TREE)
   787     public Void visitSince(SinceTree tree, Void ignore) {
   789     public Void visitSince(SinceTree tree, Void ignore) {
   788         warnIfEmpty(tree, tree.getBody());
   790         warnIfEmpty(tree, tree.getBody());
   789         return super.visitSince(tree, ignore);
   791         return super.visitSince(tree, ignore);
   790     }
   792     }
   791 
   793 
   792     @Override
   794     @Override @DefinedBy(Api.COMPILER_TREE)
   793     public Void visitThrows(ThrowsTree tree, Void ignore) {
   795     public Void visitThrows(ThrowsTree tree, Void ignore) {
   794         ReferenceTree exName = tree.getExceptionName();
   796         ReferenceTree exName = tree.getExceptionName();
   795         Element ex = env.trees.getElement(new DocTreePath(getCurrentPath(), exName));
   797         Element ex = env.trees.getElement(new DocTreePath(getCurrentPath(), exName));
   796         if (ex == null) {
   798         if (ex == null) {
   797             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
   799             env.messages.error(REFERENCE, tree, "dc.ref.not.found");
   843             if (isCheckedException(tl) && !foundThrows.contains(tl))
   845             if (isCheckedException(tl) && !foundThrows.contains(tl))
   844                 reportMissing("dc.missing.throws", tl);
   846                 reportMissing("dc.missing.throws", tl);
   845         }
   847         }
   846     }
   848     }
   847 
   849 
   848     @Override
   850     @Override @DefinedBy(Api.COMPILER_TREE)
   849     public Void visitUnknownBlockTag(UnknownBlockTagTree tree, Void ignore) {
   851     public Void visitUnknownBlockTag(UnknownBlockTagTree tree, Void ignore) {
   850         checkUnknownTag(tree, tree.getTagName());
   852         checkUnknownTag(tree, tree.getTagName());
   851         return super.visitUnknownBlockTag(tree, ignore);
   853         return super.visitUnknownBlockTag(tree, ignore);
   852     }
   854     }
   853 
   855 
   854     @Override
   856     @Override @DefinedBy(Api.COMPILER_TREE)
   855     public Void visitUnknownInlineTag(UnknownInlineTagTree tree, Void ignore) {
   857     public Void visitUnknownInlineTag(UnknownInlineTagTree tree, Void ignore) {
   856         checkUnknownTag(tree, tree.getTagName());
   858         checkUnknownTag(tree, tree.getTagName());
   857         return super.visitUnknownInlineTag(tree, ignore);
   859         return super.visitUnknownInlineTag(tree, ignore);
   858     }
   860     }
   859 
   861 
   860     private void checkUnknownTag(DocTree tree, String tagName) {
   862     private void checkUnknownTag(DocTree tree, String tagName) {
   861         if (env.customTags != null && !env.customTags.contains(tagName))
   863         if (env.customTags != null && !env.customTags.contains(tagName))
   862             env.messages.error(SYNTAX, tree, "dc.tag.unknown", tagName);
   864             env.messages.error(SYNTAX, tree, "dc.tag.unknown", tagName);
   863     }
   865     }
   864 
   866 
   865     @Override
   867     @Override @DefinedBy(Api.COMPILER_TREE)
   866     public Void visitValue(ValueTree tree, Void ignore) {
   868     public Void visitValue(ValueTree tree, Void ignore) {
   867         ReferenceTree ref = tree.getReference();
   869         ReferenceTree ref = tree.getReference();
   868         if (ref == null || ref.getSignature().isEmpty()) {
   870         if (ref == null || ref.getSignature().isEmpty()) {
   869             if (!isConstant(env.currElement))
   871             if (!isConstant(env.currElement))
   870                 env.messages.error(REFERENCE, tree, "dc.value.not.allowed.here");
   872                 env.messages.error(REFERENCE, tree, "dc.value.not.allowed.here");
   889             default:
   891             default:
   890                 return false;
   892                 return false;
   891         }
   893         }
   892     }
   894     }
   893 
   895 
   894     @Override
   896     @Override @DefinedBy(Api.COMPILER_TREE)
   895     public Void visitVersion(VersionTree tree, Void ignore) {
   897     public Void visitVersion(VersionTree tree, Void ignore) {
   896         warnIfEmpty(tree, tree.getBody());
   898         warnIfEmpty(tree, tree.getBody());
   897         return super.visitVersion(tree, ignore);
   899         return super.visitVersion(tree, ignore);
   898     }
   900     }
   899 
   901 
   900     @Override
   902     @Override @DefinedBy(Api.COMPILER_TREE)
   901     public Void visitErroneous(ErroneousTree tree, Void ignore) {
   903     public Void visitErroneous(ErroneousTree tree, Void ignore) {
   902         env.messages.error(SYNTAX, tree, null, tree.getDiagnostic().getMessage(null));
   904         env.messages.error(SYNTAX, tree, null, tree.getDiagnostic().getMessage(null));
   903         return null;
   905         return null;
   904     }
   906     }
   905     // </editor-fold>
   907     // </editor-fold>