1 4 package net.sourceforge.pmd.dfa.variableaccess; 5 6 import net.sourceforge.pmd.ast.ASTClassOrInterfaceBodyDeclaration; 7 import net.sourceforge.pmd.ast.ASTConstructorDeclaration; 8 import net.sourceforge.pmd.ast.ASTFormalParameter; 9 import net.sourceforge.pmd.ast.ASTFormalParameters; 10 import net.sourceforge.pmd.ast.ASTMethodDeclaration; 11 import net.sourceforge.pmd.ast.ASTVariableInitializer; 12 import net.sourceforge.pmd.ast.JavaParserVisitorAdapter; 13 import net.sourceforge.pmd.ast.SimpleNode; 14 import net.sourceforge.pmd.dfa.IDataFlowNode; 15 import net.sourceforge.pmd.dfa.StartOrEndDataFlowNode; 16 import net.sourceforge.pmd.symboltable.NameOccurrence; 17 import net.sourceforge.pmd.symboltable.VariableNameDeclaration; 18 19 import java.util.ArrayList ; 20 import java.util.HashSet ; 21 import java.util.Iterator ; 22 import java.util.List ; 23 import java.util.Map ; 24 import java.util.Set ; 25 26 32 public class VariableAccessVisitor extends JavaParserVisitorAdapter { 33 34 public void compute(ASTMethodDeclaration node) { 35 if (node.jjtGetParent() instanceof ASTClassOrInterfaceBodyDeclaration) { 36 this.computeNow(node); 37 } 38 } 39 40 public void compute(ASTConstructorDeclaration node) { 41 this.computeNow(node); 42 } 43 44 private void computeNow(SimpleNode node) { 45 IDataFlowNode inode = node.getDataFlowNode(); 46 47 List undefinitions = markUsages(inode); 48 49 IDataFlowNode firstINode = (IDataFlowNode) inode.getFlow().get(0); 51 firstINode.setVariableAccess(undefinitions); 52 53 IDataFlowNode lastINode = (IDataFlowNode) inode.getFlow().get(inode.getFlow().size() - 1); 55 lastINode.setVariableAccess(undefinitions); 56 } 57 58 private List markUsages(IDataFlowNode inode) { 59 List undefinitions = new ArrayList (); 61 Set variableDeclarations = collectDeclarations(inode); 62 for (Iterator i = variableDeclarations.iterator(); i.hasNext();) { 63 Map declarations = (Map ) i.next(); 64 for (Iterator j = declarations.entrySet().iterator(); j.hasNext();) { 65 Map.Entry entry = (Map.Entry ) j.next(); 66 VariableNameDeclaration vnd = (VariableNameDeclaration) entry.getKey(); 67 68 if (vnd.getAccessNodeParent() instanceof ASTFormalParameter) { 69 addVariableAccess( 71 (SimpleNode)vnd.getNode().getFirstParentOfType(ASTFormalParameters.class), 72 new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()), 73 inode.getFlow()); 74 } else if (vnd.getAccessNodeParent().getFirstChildOfType(ASTVariableInitializer.class) != null) { 75 addVariableAccess( 77 vnd.getNode(), 78 new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()), 79 inode.getFlow()); 80 } 81 undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage())); 82 83 for (Iterator k = ((List ) entry.getValue()).iterator(); k.hasNext();) { 84 addAccess(k, inode); 85 } 86 } 87 } 88 return undefinitions; 89 } 90 91 private Set collectDeclarations(IDataFlowNode inode) { 92 Set decls = new HashSet (); 93 Map varDecls; 94 for (int i = 0; i < inode.getFlow().size(); i++) { 95 IDataFlowNode n = (IDataFlowNode) inode.getFlow().get(i); 96 if (n instanceof StartOrEndDataFlowNode) { 97 continue; 98 } 99 varDecls = n.getSimpleNode().getScope().getVariableDeclarations(); 100 if (!decls.contains(varDecls)) { 101 decls.add(varDecls); 102 } 103 } 104 return decls; 105 } 106 107 private void addAccess(Iterator k, IDataFlowNode inode) { 108 NameOccurrence occurrence = (NameOccurrence) k.next(); 109 if (occurrence.isOnLeftHandSide()) { 110 this.addVariableAccess(occurrence.getLocation(), new VariableAccess(VariableAccess.DEFINITION, occurrence.getImage()), inode.getFlow()); 111 } else if (occurrence.isOnRightHandSide() || (!occurrence.isOnLeftHandSide() && !occurrence.isOnRightHandSide())) { 112 this.addVariableAccess(occurrence.getLocation(), new VariableAccess(VariableAccess.REFERENCING, occurrence.getImage()), inode.getFlow()); 113 } 114 } 115 116 122 private void addVariableAccess(SimpleNode node, VariableAccess va, List flow) { 123 for (int i = flow.size()-1; i > 0; i--) { 125 IDataFlowNode inode = (IDataFlowNode) flow.get(i); 126 if (inode.getSimpleNode() == null) { 127 continue; 128 } 129 130 List children = inode.getSimpleNode().findChildrenOfType(node.getClass()); 131 Iterator childrenIterator = children.iterator(); 132 while (childrenIterator.hasNext()) { 133 if (node.equals(childrenIterator.next())) { 134 List v = new ArrayList (); 135 v.add(va); 136 inode.setVariableAccess(v); 137 return; 138 } 139 } 140 } 141 } 142 143 } 144 | Popular Tags |