View Javadoc

    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   * A rule to manage those who just can't shut up...
    13   *
    14   * @author Brian Remedios
    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;	// start from top
    40  		 for (; start<lines.length; start++ ) {
    41  			 if (hasRealText(lines[start])) break;
    42  		 }
    43
    44  		  int end = lines.length - 1;	// go up from bottom
    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  }