001: /**
002: * Created on Aug 29, 2002
003: */package org.acm.seguin.pmd.rules.design;
004:
005: import net.sourceforge.jrefactory.ast.ASTStatement;
006: import net.sourceforge.jrefactory.ast.ASTSwitchLabel;
007: import net.sourceforge.jrefactory.ast.ASTSwitchStatement;
008: import org.acm.seguin.pmd.stat.DataPoint;
009: import org.acm.seguin.pmd.stat.StatisticalRule;
010:
011: /**
012: * @author dpeugh
013: *
014: * Switch Density - This is the number of statements over the
015: * number of cases within a switch. The higher the value, the
016: * more work each case is doing.
017: *
018: * Its my theory, that when the Switch Density is high, you should
019: * start looking at Subclasses or State Pattern to alleviate the
020: * problem.
021: */
022: public class SwitchDensityRule extends StatisticalRule {
023: private class SwitchDensity {
024: private int labels = 0;
025: private int stmts = 0;
026:
027: public SwitchDensity() {
028: }
029:
030: public void addSwitchLabel() {
031: labels++;
032: }
033:
034: public void addStatement() {
035: stmts++;
036: }
037:
038: public void addStatements(int stmtCount) {
039: stmts += stmtCount;
040: }
041:
042: public int getStatementCount() {
043: return stmts;
044: }
045:
046: public double getDensity() {
047: if (labels == 0) {
048: return 0;
049: }
050: return 1.0 * (stmts / labels);
051: }
052: }
053:
054: public SwitchDensityRule() {
055: super ();
056: }
057:
058: public Object visit(ASTSwitchStatement node, Object data) {
059: SwitchDensity oldData = null;
060:
061: if (data instanceof SwitchDensity) {
062: oldData = (SwitchDensity) data;
063: }
064:
065: SwitchDensity density = new SwitchDensity();
066:
067: node.childrenAccept(this , density);
068:
069: DataPoint point = new DataPoint();
070: point.setLineNumber(node.getBeginLine());
071: point.setScore(density.getDensity());
072: point.setRule(this );
073: point.setMessage(getMessage());
074:
075: addDataPoint(point);
076:
077: if (data instanceof SwitchDensity) {
078: ((SwitchDensity) data).addStatements(density
079: .getStatementCount());
080: }
081: return oldData;
082: }
083:
084: public Object visit(ASTStatement statement, Object data) {
085: if (data instanceof SwitchDensity) {
086: ((SwitchDensity) data).addStatement();
087: }
088:
089: statement.childrenAccept(this , data);
090:
091: return data;
092: }
093:
094: public Object visit(ASTSwitchLabel switchLabel, Object data) {
095: if (data instanceof SwitchDensity) {
096: ((SwitchDensity) data).addSwitchLabel();
097: }
098:
099: switchLabel.childrenAccept(this, data);
100: return data;
101: }
102: }
|