001: package net.sourceforge.pmd.rules;
002:
003: import net.sourceforge.pmd.AbstractRule;
004: import net.sourceforge.pmd.RuleContext;
005: import net.sourceforge.pmd.ast.ASTMethodDeclaration;
006: import net.sourceforge.pmd.dfa.IDataFlowNode;
007: import net.sourceforge.pmd.dfa.pathfinder.CurrentPath;
008: import net.sourceforge.pmd.dfa.pathfinder.DAAPathFinder;
009: import net.sourceforge.pmd.dfa.pathfinder.Executable;
010: import net.sourceforge.pmd.dfa.variableaccess.VariableAccess;
011:
012: import java.util.HashMap;
013: import java.util.Iterator;
014: import java.util.Map;
015:
016: public class UselessAssignment extends AbstractRule implements
017: Executable {
018:
019: private RuleContext rc;
020:
021: public Object visit(ASTMethodDeclaration node, Object data) {
022: this .rc = (RuleContext) data;
023:
024: /*
025: IDataFlowNode n1 = node.getDataFlowNode();
026: List f = n1.getFlow();
027: for (Iterator i = f.iterator(); i.hasNext();) {
028: DataFlowNode dfan = (DataFlowNode)i.next();
029: System.out.println(dfan);
030: List va = dfan.getVariableAccess();
031: for (Iterator j = va.iterator(); j.hasNext();) {
032: VariableAccess o = (VariableAccess)j.next();
033: System.out.println(o);
034: }
035: }
036: */
037:
038: DAAPathFinder a = new DAAPathFinder(node.getDataFlowNode()
039: .getFlow().get(0), this );
040: a.run();
041:
042: return data;
043: }
044:
045: private static class Usage {
046: public int accessType;
047: public IDataFlowNode node;
048:
049: public Usage(int accessType, IDataFlowNode node) {
050: this .accessType = accessType;
051: this .node = node;
052: }
053:
054: public String toString() {
055: return "accessType = " + accessType + ", line = "
056: + node.getLine();
057: }
058: }
059:
060: public void execute(CurrentPath path) {
061: Map<String, Usage> hash = new HashMap<String, Usage>();
062: //System.out.println("path size is " + path.size());
063: for (Iterator<IDataFlowNode> i = path.iterator(); i.hasNext();) {
064: //System.out.println("i = " + i);
065: IDataFlowNode inode = i.next();
066: if (inode.getVariableAccess() == null) {
067: continue;
068: }
069: for (int j = 0; j < inode.getVariableAccess().size(); j++) {
070: VariableAccess va = inode.getVariableAccess().get(j);
071: //System.out.println("inode = " + inode + ", va = " + va);
072: Usage u = hash.get(va.getVariableName());
073: if (u != null) {
074: // At some point investigate and possibly reintroduce this line2 thing
075: //int line2 = ((Integer) array.get(1)).intValue();
076:
077: // DD - definition followed by another definition
078: // FIXME need to check for assignment as well!
079: if (va.isDefinition()
080: && va.accessTypeMatches(u.accessType)) {
081: //System.out.println(va.getVariableName() + ":" + u);
082: addViolation(rc, u.node.getSimpleNode(), va
083: .getVariableName());
084: }
085: /* // UR - ??
086: else if (last == VariableAccess.UNDEFINITION && va.isReference()) {
087: //this.rc.getReport().addRuleViolation(createRuleViolation(rc, inode.getSimpleNode(), va.getVariableName(), "UR"));
088: }
089: // DU - variable is defined and then goes out of scope
090: // i.e., unused parameter
091: else if (last == VariableAccess.DEFINITION && va.isUndefinition()) {
092: if (inode.getSimpleNode() != null) {
093: this.rc.getReport().addRuleViolation(createRuleViolation(rc, tmp, va.getVariableName(), "DU"));
094: }
095: }
096: */
097: }
098: u = new Usage(va.getAccessType(), inode);
099: hash.put(va.getVariableName(), u);
100: }
101: }
102: }
103: }
|