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