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; |
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> |