01: /**
02: * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
03: */package net.sourceforge.pmd.rules.design;
04:
05: import net.sourceforge.pmd.ast.ASTStatement;
06: import net.sourceforge.pmd.ast.ASTSwitchLabel;
07: import net.sourceforge.pmd.ast.ASTSwitchStatement;
08: import net.sourceforge.pmd.stat.DataPoint;
09: import net.sourceforge.pmd.stat.StatisticalRule;
10:
11: /**
12: * @author David Dixon-Peugh
13: *
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
73: .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: }
|