View Javadoc

    1   /***
    2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
    3    */
    4   package net.sourceforge.pmd.rules.design;
    5
    6   import net.sourceforge.pmd.ast.ASTStatement;
    7   import net.sourceforge.pmd.ast.ASTSwitchLabel;
    8   import net.sourceforge.pmd.ast.ASTSwitchStatement;
    9   import net.sourceforge.pmd.stat.DataPoint;
    10  import net.sourceforge.pmd.stat.StatisticalRule;
    11
    12  /***
    13   * @author dpeugh
    14   *         <p/>
    15   *         Switch Density - This is the number of statements over the
    16   *         number of cases within a switch.  The higher the value, the
    17   *         more work each case is doing.
    18   *         <p/>
    19   *         Its my theory, that when the Switch Density is high, you should
    20   *         start looking at Subclasses or State Pattern to alleviate the
    21   *         problem.
    22   */
    23  public class SwitchDensityRule extends StatisticalRule {
    24
    25      private static class SwitchDensity {
    26          private int labels = 0;
    27          private int stmts = 0;
    28
    29          public void addSwitchLabel() {
    30              labels++;
    31          }
    32
    33          public void addStatement() {
    34              stmts++;
    35          }
    36
    37          public void addStatements(int stmtCount) {
    38              stmts += stmtCount;
    39          }
    40
    41          public int getStatementCount() {
    42              return stmts;
    43          }
    44
    45          public double getDensity() {
    46              if (labels == 0) {
    47                  return 0;
    48              }
    49              return (double) stmts / (double) labels;
    50          }
    51      }
    52
    53      public Object visit(ASTSwitchStatement node, Object data) {
    54          SwitchDensity oldData = null;
    55
    56          if (data instanceof SwitchDensity) {
    57              oldData = (SwitchDensity) data;
    58          }
    59
    60          SwitchDensity density = new SwitchDensity();
    61
    62          node.childrenAccept(this, density);
    63
    64          DataPoint point = new DataPoint();
    65          point.setNode(node);
    66          point.setScore(density.getDensity());
    67          point.setMessage(getMessage());
    68
    69          addDataPoint(point);
    70
    71          if (data instanceof SwitchDensity) {
    72              ((SwitchDensity) data).addStatements(density.getStatementCount());
    73          }
    74          return oldData;
    75      }
    76
    77      public Object visit(ASTStatement statement, Object data) {
    78          if (data instanceof SwitchDensity) {
    79              ((SwitchDensity) data).addStatement();
    80          }
    81
    82          statement.childrenAccept(this, data);
    83
    84          return data;
    85      }
    86
    87      public Object visit(ASTSwitchLabel switchLabel, Object data) {
    88          if (data instanceof SwitchDensity) {
    89              ((SwitchDensity) data).addSwitchLabel();
    90          }
    91
    92          switchLabel.childrenAccept(this, data);
    93          return data;
    94      }
    95  }