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", 1, 200, 80, 2.0f);
23
24 private static final String CR = "\n";
25
26 public CommentSizeRule() {
27 definePropertyDescriptor(MAX_LINES);
28 definePropertyDescriptor(MAX_LINE_LENGTH);
29 }
30
31 private static boolean hasRealText(String line) {
32
33 if (StringUtil.isEmpty(line)) return false;
34
35 return ! StringUtil.isAnyOf(line.trim(), "//", "/*", "/**", "*", "*/");
36 }
37
38 private boolean hasTooManyLines(Comment comment) {
39
40 String[] lines = comment.getImage().split(CR);
41
42 int start = 0;
43 for (; start<lines.length; start++ ) {
44 if (hasRealText(lines[start])) break;
45 }
46
47 int end = lines.length - 1;
48 for (; end>0; end-- ) {
49 if (hasRealText(lines[end])) break;
50 }
51
52 int lineCount = end - start + 1;
53
54 return lineCount > getProperty(MAX_LINES);
55 }
56
57 private String withoutCommentMarkup(String text) {
58
59 return StringUtil.withoutPrefixes(text.trim(), "//", "*", "/**");
60 }
61
62 private List<Integer> overLengthLineIndicesIn(Comment comment) {
63
64 int maxLength = getProperty(MAX_LINE_LENGTH);
65
66 List<Integer> indicies = new ArrayList<Integer>();
67 String[] lines = comment.getImage().split(CR);
68
69 int offset = comment.getBeginLine();
70
71 for (int i=0; i<lines.length; i++) {
72 String cleaned = withoutCommentMarkup(lines[i]);
73 if (cleaned.length() > maxLength) indicies.add(i+offset);
74 }
75
76 return indicies;
77 }
78
79 @Override
80 public Object visit(ASTCompilationUnit cUnit, Object data) {
81
82 for (Comment comment : cUnit.getComments()) {
83 if (hasTooManyLines(comment)) {
84 addViolationWithMessage(data, cUnit,
85 this.getMessage() + ": Too many lines",
86 comment.getBeginLine(), comment.getEndLine());
87 }
88
89 List<Integer> lineNumbers = overLengthLineIndicesIn(comment);
90 if (lineNumbers.isEmpty()) continue;
91
92 for (Integer lineNum : lineNumbers) {
93 addViolationWithMessage(data, cUnit,
94 this.getMessage() + ": Line too long",
95 lineNum, lineNum);
96 }
97 }
98
99 return super.visit(cUnit, data);
100 }
101 }