Clover coverage report - PMD - 3.9
Coverage timestamp: Tue Dec 19 2006 09:38:44 EST
file stats: LOC: 193   Methods: 10
NCLOC: 126   Classes: 2
 
 Source file Conditionals Statements Methods TOTAL
DaaRule.java 87.5% 94.5% 80% 91%
coverage coverage
 1    /*
 2    * Created on 20.07.2004
 3    */
 4    package net.sourceforge.pmd.dfa;
 5   
 6    import net.sourceforge.pmd.AbstractRule;
 7    import net.sourceforge.pmd.PropertyDescriptor;
 8    import net.sourceforge.pmd.RuleContext;
 9    import net.sourceforge.pmd.ast.ASTClassOrInterfaceDeclaration;
 10    import net.sourceforge.pmd.ast.ASTMethodDeclaration;
 11    import net.sourceforge.pmd.ast.SimpleNode;
 12    import net.sourceforge.pmd.dfa.pathfinder.CurrentPath;
 13    import net.sourceforge.pmd.dfa.pathfinder.DAAPathFinder;
 14    import net.sourceforge.pmd.dfa.pathfinder.Executable;
 15    import net.sourceforge.pmd.dfa.variableaccess.VariableAccess;
 16    import net.sourceforge.pmd.properties.IntegerProperty;
 17   
 18    import java.text.MessageFormat;
 19    import java.util.ArrayList;
 20    import java.util.Hashtable;
 21    import java.util.Iterator;
 22    import java.util.List;
 23    import java.util.Map;
 24   
 25    /**
 26    * Starts path search for each method and runs code if found.
 27    *
 28    * @author raik
 29    * @author Sven Jacob
 30    */
 31    public class DaaRule extends AbstractRule implements Executable {
 32    private RuleContext rc;
 33    private List daaRuleViolations;
 34    private int maxRuleViolations;
 35    private int currentRuleViolationCount;
 36   
 37    private static final PropertyDescriptor maxPathDescriptor = new IntegerProperty(
 38    "maxpaths", "Maximum number of paths per method", 5000, 1.0f
 39    );
 40   
 41    private static final PropertyDescriptor maxViolationsDescriptor = new IntegerProperty(
 42    "maxviolations", "Maximum number of anomalys per class", 1000, 2.0f
 43    );
 44   
 45    private static final Map propertyDescriptorsByName = asFixedMap(
 46    new PropertyDescriptor[] { maxPathDescriptor, maxViolationsDescriptor});
 47   
 48  0 protected Map propertiesByName() {
 49  0 return propertyDescriptorsByName;
 50    }
 51   
 52    private static class Usage {
 53    public int accessType;
 54    public IDataFlowNode node;
 55   
 56  45 public Usage(int accessType, IDataFlowNode node) {
 57  45 this.accessType = accessType;
 58  45 this.node = node;
 59    }
 60   
 61  0 public String toString() {
 62  0 return "accessType = " + accessType + ", line = " + node.getLine();
 63    }
 64    }
 65   
 66  5 public Object visit(ASTClassOrInterfaceDeclaration node, Object data) {
 67  5 this.maxRuleViolations = getIntProperty(maxViolationsDescriptor);
 68  5 this.currentRuleViolationCount = 0;
 69  5 return super.visit(node, data);
 70    }
 71   
 72  5 public Object visit(ASTMethodDeclaration methodDeclaration, Object data) {
 73  5 this.rc = (RuleContext) data;
 74  5 this.daaRuleViolations = new ArrayList();
 75   
 76  5 final IDataFlowNode node = (IDataFlowNode) methodDeclaration.getDataFlowNode().getFlow().get(0);
 77   
 78  5 final DAAPathFinder pathFinder = new DAAPathFinder(node, this, getIntProperty(maxPathDescriptor));
 79  5 pathFinder.run();
 80   
 81  5 super.visit(methodDeclaration, data);
 82  5 return data;
 83    }
 84   
 85  7 public void execute(CurrentPath path) {
 86  7 if (maxNumberOfViolationsReached()) {
 87    // dont execute this path if the limit is already reached
 88  0 return;
 89    }
 90   
 91  7 final Hashtable hash = new Hashtable();
 92   
 93  7 final Iterator pathIterator = path.iterator();
 94  7 while (pathIterator.hasNext()) {
 95    // iterate all nodes in this path
 96  42 IDataFlowNode inode = (IDataFlowNode) pathIterator.next();
 97  42 if (inode.getVariableAccess() != null) {
 98    // iterate all variables of this node
 99  42 for (int g = 0; g < inode.getVariableAccess().size(); g++) {
 100  45 final VariableAccess va = (VariableAccess) inode.getVariableAccess().get(g);
 101   
 102    // get the last usage of the current variable
 103  45 final Usage lastUsage = (Usage) hash.get(va.getVariableName());
 104  45 if (lastUsage != null) {
 105    // there was a usage to this variable before
 106  34 checkVariableAccess(inode, va, lastUsage);
 107    }
 108   
 109  45 final Usage newUsage = new Usage(va.getAccessType(), inode);
 110    // put the new usage for the variable
 111  45 hash.put(va.getVariableName(), newUsage);
 112    }
 113    }
 114    }
 115    }
 116   
 117    /**
 118    * @param inode
 119    * @param va
 120    * @param o
 121    */
 122  34 private void checkVariableAccess(IDataFlowNode inode, VariableAccess va, final Usage u) {
 123    // get the start and end line
 124  34 final int startLine = u.node.getLine();
 125  34 final int endLine = inode.getLine();
 126   
 127  34 final SimpleNode lastNode = inode.getSimpleNode();
 128  34 final SimpleNode firstNode = u.node.getSimpleNode();
 129   
 130  34 if (va.accessTypeMatches(u.accessType) && va.isDefinition() ) { // DD
 131  2 addDaaViolation(rc, lastNode, "DD", va.getVariableName(), startLine, endLine);
 132  32 } else if (u.accessType == VariableAccess.UNDEFINITION && va.isReference()) { // UR
 133  1 addDaaViolation(rc, lastNode, "UR", va.getVariableName(), startLine, endLine);
 134  31 } else if (u.accessType == VariableAccess.DEFINITION && va.isUndefinition()) { // DU
 135  5 addDaaViolation(rc, firstNode, "DU", va.getVariableName(), startLine, endLine);
 136    }
 137    }
 138   
 139    /**
 140    * Adds a daa violation to the report.
 141    *
 142    * @param ctx the RuleContext
 143    * @param node the node that produces the violation
 144    * @param msg specific message to put in the report
 145    */
 146  8 private final void addDaaViolation(Object data, SimpleNode node, String type, String var, int startLine, int endLine) {
 147  8 if (!maxNumberOfViolationsReached()
 148    && !violationAlreadyExists(type, var, startLine, endLine)
 149    && node != null) {
 150  7 final RuleContext ctx = (RuleContext) data;
 151  7 final Object[] params = new Object[] { type, var, new Integer(startLine), new Integer(endLine) };
 152  7 String msg = type;
 153  7 if (getMessage() != null) {
 154  7 msg = MessageFormat.format(getMessage(), params);
 155    }
 156  7 final DaaRuleViolation violation = new DaaRuleViolation(this, ctx, node, type, msg, var, startLine, endLine);
 157  7 ctx.getReport().addRuleViolation(violation);
 158  7 this.daaRuleViolations.add(violation);
 159  7 this.currentRuleViolationCount++;
 160    }
 161    }
 162   
 163    /**
 164    * Maximum number of violations was already reached?
 165    * @return
 166    */
 167  15 private boolean maxNumberOfViolationsReached() {
 168  15 return this.currentRuleViolationCount >= this.maxRuleViolations;
 169    }
 170   
 171    /**
 172    * Checks if a violation already exists.
 173    * This is needed because on the different paths same anomalies can occur.
 174    * @param type
 175    * @param var
 176    * @param startLine
 177    * @param endLine
 178    * @return true if the violation already was added to the report
 179    */
 180  8 private boolean violationAlreadyExists(String type, String var, int startLine, int endLine) {
 181  8 final Iterator violationIterator = this.daaRuleViolations.iterator();
 182  8 while (violationIterator.hasNext()) {
 183  8 final DaaRuleViolation violation = (DaaRuleViolation)violationIterator.next();
 184  8 if ((violation.getBeginLine() == startLine)
 185    && (violation.getEndLine() == endLine)
 186    && violation.getType().equals(type)
 187    && violation.getVariableName().equals(var)) {
 188  1 return true;
 189    }
 190    }
 191  7 return false;
 192    }
 193    }