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