source: josm/trunk/tools/checkstyle/src/org/openstreetmap/josm/TopLevelJavadocCheck.java@ 12587

Last change on this file since 12587 was 12587, checked in by bastiK, 7 years ago

see #14794 - fix NPE

  • Property svn:eol-style set to native
File size: 3.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm;
3
4import com.puppycrawl.tools.checkstyle.JavadocDetailNodeParser;
5import com.puppycrawl.tools.checkstyle.api.AbstractCheck;
6import com.puppycrawl.tools.checkstyle.api.DetailAST;
7import com.puppycrawl.tools.checkstyle.api.DetailNode;
8import com.puppycrawl.tools.checkstyle.api.JavadocTokenTypes;
9import com.puppycrawl.tools.checkstyle.api.TokenTypes;
10import com.puppycrawl.tools.checkstyle.utils.JavadocUtils;
11
12/**
13 * Checks that there is Javadoc for every top level class, interface or enum.
14 */
15public class TopLevelJavadocCheck extends AbstractCheck {
16
17 private boolean foundTopLevelClass;
18
19 @Override
20 public int[] getAcceptableTokens() {
21 return getDefaultTokens();
22 }
23
24 @Override
25 public int[] getDefaultTokens() {
26 return new int[]{TokenTypes.CLASS_DEF, TokenTypes.INTERFACE_DEF, TokenTypes.ENUM_DEF};
27 }
28
29 @Override
30 public int[] getRequiredTokens() {
31 return new int[0];
32 }
33
34 @Override
35 public boolean isCommentNodesRequired() {
36 return true;
37 }
38
39 @Override
40 public void beginTree(DetailAST rootAST) {
41 foundTopLevelClass = false;
42 }
43
44 @Override
45 public void finishTree(DetailAST rootAST) {
46 if (!foundTopLevelClass) {
47 this.log(rootAST.getLineNo(), "assertion failure: unable to find toplevel class or interface");
48 }
49 }
50
51 private boolean hasJavadoc(DetailAST ast) {
52 DetailAST blockCommentBegin = ast.findFirstToken(TokenTypes.BLOCK_COMMENT_BEGIN);
53 if (blockCommentBegin == null) {
54 DetailAST modifiers = ast.findFirstToken(TokenTypes.MODIFIERS);
55 if (modifiers == null)
56 return false;
57 blockCommentBegin = modifiers.findFirstToken(TokenTypes.BLOCK_COMMENT_BEGIN);
58 if (blockCommentBegin == null) {
59 DetailAST annotation = modifiers.findFirstToken(TokenTypes.ANNOTATION);
60 if (annotation == null)
61 return false;
62 blockCommentBegin = annotation.findFirstToken(TokenTypes.BLOCK_COMMENT_BEGIN);
63 if (blockCommentBegin == null)
64 return false;
65 }
66 }
67 if (!JavadocUtils.isJavadocComment(blockCommentBegin))
68 return false;
69 DetailNode javadocTree = new JavadocDetailNodeParser().parseJavadocAsDetailNode(blockCommentBegin).getTree();
70 return hasProperText(javadocTree);
71 }
72
73 private boolean hasProperText(DetailNode javadoc) {
74 if (javadoc == null) return false;
75 for (DetailNode child : javadoc.getChildren()) {
76 if (child.getType() == JavadocTokenTypes.TEXT) {
77 if (!child.getText().trim().isEmpty())
78 return true;
79 } else if (child.getType() == JavadocTokenTypes.HTML_ELEMENT) {
80 return true;
81 }
82 }
83 return false;
84 }
85
86 @Override
87 public void visitToken(DetailAST ast) {
88 DetailAST parent = ast.getParent();
89 if (parent == null || parent.getType() == TokenTypes.EOF) {
90 foundTopLevelClass = true;
91 if (!hasJavadoc(ast)) {
92 this.log(ast.getLineNo(), "incomplete or missing Javadoc for top level class or interface");
93 }
94 }
95 }
96}
Note: See TracBrowser for help on using the repository browser.