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  }