1
2
3
4 package net.sourceforge.pmd.lang.java.rule.comments;
5
6 import java.util.ArrayList;
7 import java.util.List;
8
9 import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
10 import net.sourceforge.pmd.lang.java.ast.Comment;
11 import net.sourceforge.pmd.lang.rule.properties.IntegerProperty;
12 import net.sourceforge.pmd.util.StringUtil;
13
14
15
16
17
18
19 public class CommentSizeRule extends AbstractCommentRule {
20
21 public static final IntegerProperty MAX_LINES = new IntegerProperty("maxLines", "Maximum lines", 2, 200, 6, 2.0f);
22 public static final IntegerProperty MAX_LINE_LENGTH = new IntegerProperty("maxLineLength", "Maximum line length",
23 1, 200, 80, 2.0f);
24
25 private static final String CR = "\n";
26
27 public CommentSizeRule() {
28 definePropertyDescriptor(MAX_LINES);
29 definePropertyDescriptor(MAX_LINE_LENGTH);
30 }
31
32 private static boolean hasRealText(String line) {
33
34 if (StringUtil.isEmpty(line)) {
35 return false;
36 }
37
38 return !StringUtil.isAnyOf(line.trim(), "//", "/*", "/**", "*", "*/");
39 }
40
41 private boolean hasTooManyLines(Comment comment) {
42
43 String[] lines = comment.getImage().split(CR);
44
45 int start = 0;
46 for (; start < lines.length; start++) {
47 if (hasRealText(lines[start])) {
48 break;
49 }
50 }
51
52 int end = lines.length - 1;
53 for (; end > 0; end--) {
54 if (hasRealText(lines[end])) {
55 break;
56 }
57 }
58
59 int lineCount = end - start + 1;
60
61 return lineCount > getProperty(MAX_LINES);
62 }
63
64 private String withoutCommentMarkup(String text) {
65
66 return StringUtil.withoutPrefixes(text.trim(), "//", "*", "/**");
67 }
68
69 private List<Integer> overLengthLineIndicesIn(Comment comment) {
70
71 int maxLength = getProperty(MAX_LINE_LENGTH);
72
73 List<Integer> indicies = new ArrayList<Integer>();
74 String[] lines = comment.getImage().split(CR);
75
76 int offset = comment.getBeginLine();
77
78 for (int i = 0; i < lines.length; i++) {
79 String cleaned = withoutCommentMarkup(lines[i]);
80 if (cleaned.length() > maxLength) {
81 indicies.add(i + offset);
82 }
83 }
84
85 return indicies;
86 }
87
88 @Override
89 public Object visit(ASTCompilationUnit cUnit, Object data) {
90
91 for (Comment comment : cUnit.getComments()) {
92 if (hasTooManyLines(comment)) {
93 addViolationWithMessage(data, cUnit, this.getMessage() + ": Too many lines", comment.getBeginLine(),
94 comment.getEndLine());
95 }
96
97 List<Integer> lineNumbers = overLengthLineIndicesIn(comment);
98 if (lineNumbers.isEmpty()) {
99 continue;
100 }
101
102 for (Integer lineNum : lineNumbers) {
103 addViolationWithMessage(data, cUnit, this.getMessage() + ": Line too long", lineNum, lineNum);
104 }
105 }
106
107 return super.visit(cUnit, data);
108 }
109 }