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 1.0 * (stmts / 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.setLineNumber(node.getBeginLine());
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  }