/**
* BSD-style license; for more info see http://pmd.sourceforge.net/license.html
*/
package net.sourceforge.pmd.lang.java.rule.comments;
import java.util.ArrayList;
import java.util.List;
import net.sourceforge.pmd.lang.java.ast.ASTCompilationUnit;
import net.sourceforge.pmd.lang.java.ast.Comment;
import net.sourceforge.pmd.lang.rule.properties.IntegerProperty;
import net.sourceforge.pmd.util.StringUtil;
/**
* A rule to manage those who just can't shut up...
*
* @author Brian Remedios
*/
public class CommentSizeRule extends AbstractCommentRule {
public static final IntegerProperty MAX_LINES = new IntegerProperty("maxLines", "Maximum lines", 2, 200, 6, 2.0f);
public static final IntegerProperty MAX_LINE_LENGTH = new IntegerProperty("maxLineLength", "Maximum line length", 1,
200, 80, 2.0f);
private static final String CR = "\n";
public CommentSizeRule() {
definePropertyDescriptor(MAX_LINES);
definePropertyDescriptor(MAX_LINE_LENGTH);
}
private static boolean hasRealText(String line) {
if (StringUtil.isEmpty(line)) {
return false;
}
return !StringUtil.isAnyOf(line.trim(), "//", "/*", "/**", "*", "*/");
}
private boolean hasTooManyLines(Comment comment) {
String[] lines = comment.getImage().split(CR);
int start = 0; // start from top
for (; start < lines.length; start++) {
if (hasRealText(lines[start])) {
break;
}
}
int end = lines.length - 1; // go up from bottom
for (; end > 0; end--) {
if (hasRealText(lines[end])) {
break;
}
}
int lineCount = end - start + 1;
return lineCount > getProperty(MAX_LINES);
}
private String withoutCommentMarkup(String text) {
return StringUtil.withoutPrefixes(text.trim(), "//", "*", "/**");
}
private List<Integer> overLengthLineIndicesIn(Comment comment) {
int maxLength = getProperty(MAX_LINE_LENGTH);
List<Integer> indicies = new ArrayList<>();
String[] lines = comment.getImage().split(CR);
int offset = comment.getBeginLine();
for (int i = 0; i < lines.length; i++) {
String cleaned = withoutCommentMarkup(lines[i]);
if (cleaned.length() > maxLength) {
indicies.add(i + offset);
}
}
return indicies;
}
@Override
public Object visit(ASTCompilationUnit cUnit, Object data) {
for (Comment comment : cUnit.getComments()) {
if (hasTooManyLines(comment)) {
addViolationWithMessage(data, cUnit, this.getMessage() + ": Too many lines", comment.getBeginLine(),
comment.getEndLine());
}
List<Integer> lineNumbers = overLengthLineIndicesIn(comment);
if (lineNumbers.isEmpty()) {
continue;
}
for (Integer lineNum : lineNumbers) {
addViolationWithMessage(data, cUnit, this.getMessage() + ": Line too long", lineNum, lineNum);
}
}
return super.visit(cUnit, data);
}
}