Clover coverage report - PMD - 3.7 Coverage timestamp: Wed May 31 2006 09:25:59 EDT FRAMES NO FRAMES |
file stats: | LOC: | 107 |  | Methods: | 7
| NCLOC: | 82 |  | Classes: | 1
Source file | Conditionals | Statements | Methods | TOTAL
VariableAccessVisitor.java | 90.9% | 97.4% | 85.7% | 94.1% |

1 |  | /*
2 |  | * Created on 14.07.2004
3 |  | */
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.ASTMethodDeclaration;
9 |  | import net.sourceforge.pmd.ast.JavaParserVisitorAdapter;
10 |  | import net.sourceforge.pmd.ast.SimpleNode;
11 |  | import net.sourceforge.pmd.dfa.IDataFlowNode;
12 |  | import net.sourceforge.pmd.dfa.StartOrEndDataFlowNode;
13 |  | import net.sourceforge.pmd.symboltable.NameOccurrence;
14 |  | import net.sourceforge.pmd.symboltable.VariableNameDeclaration;
15 |  |
16 |  | import java.util.ArrayList;
17 |  | import java.util.HashSet;
18 |  | import java.util.Iterator;
19 |  | import java.util.List;
20 |  | import java.util.Map;
21 |  | import java.util.Set;
22 |  | import java.util.Vector;
23 |  |
24 |  | /**
25 |  | * @author raik
26 |  | * <p/>
27 |  | * Searches for special nodes and computes based on the sequence, the type of
28 |  | * access of a variable.
29 |  | */
30 |  | public class VariableAccessVisitor extends JavaParserVisitorAdapter {
31 |  |
32 | 38 | public void compute(ASTMethodDeclaration node) {
33 | 38 | if (node.jjtGetParent() instanceof ASTClassOrInterfaceBodyDeclaration) {
34 | 38 | this.computeNow(node);
35 |  | }
36 |  | }
37 |  |
38 | 0 | public void compute(ASTConstructorDeclaration node) {
39 | 0 | this.computeNow(node);
40 |  | }
41 |  |
42 | 38 | private void computeNow(SimpleNode node) {
43 | 38 | IDataFlowNode inode = node.getDataFlowNode();
44 |  |
45 | 38 | List undefinitions = markUsages(inode);
46 |  |
47 |  | // is this necessary? Why does the first node need undefs?
48 | 38 | IDataFlowNode firstINode = (IDataFlowNode) inode.getFlow().get(0);
49 | 38 | firstINode.setVariableAccess(undefinitions);
50 |  |
51 | 38 | IDataFlowNode lastINode = (IDataFlowNode) inode.getFlow().get(inode.getFlow().size() - 1);
52 | 38 | lastINode.setVariableAccess(undefinitions);
53 |  | }
54 |  |
55 | 38 | private List markUsages(IDataFlowNode inode) {
56 |  | // undefinitions was once a field... seems like it works fine as a local
57 | 38 | List undefinitions = new ArrayList();
58 | 38 | Set variableDeclarations = collectDeclarations(inode);
59 | 38 | for (Iterator i = variableDeclarations.iterator(); i.hasNext();) {
60 | 75 | Map declarations = (Map) i.next();
61 | 75 | for (Iterator j = declarations.keySet().iterator(); j.hasNext();) {
62 | 38 | VariableNameDeclaration vnd = (VariableNameDeclaration) j.next();
63 | 38 | addVariableAccess(vnd.getNode().getBeginLine(), new VariableAccess(VariableAccess.DEFINITION, vnd.getImage()), inode.getFlow());
64 | 38 | undefinitions.add(new VariableAccess(VariableAccess.UNDEFINITION, vnd.getImage()));
65 | 38 | for (Iterator k = ((List) declarations.get(vnd)).iterator(); k.hasNext();) {
66 | 114 | addAccess(k, inode);
67 |  | }
68 |  | }
69 |  | }
70 | 38 | return undefinitions;
71 |  | }
72 |  |
73 | 38 | private Set collectDeclarations(IDataFlowNode inode) {
74 | 38 | Set decls = new HashSet();
75 | 38 | for (int i = 0; i < inode.getFlow().size(); i++) {
76 | 284 | IDataFlowNode n = (IDataFlowNode) inode.getFlow().get(i);
77 | 284 | if (n instanceof StartOrEndDataFlowNode) {
78 | 76 | continue;
79 |  | }
80 | 208 | if (!decls.contains(n.getSimpleNode().getScope().getVariableDeclarations())) {
81 | 75 | decls.add(n.getSimpleNode().getScope().getVariableDeclarations());
82 |  | }
83 |  | }
84 | 38 | return decls;
85 |  | }
86 |  |
87 | 114 | private void addAccess(Iterator k, IDataFlowNode inode) {
88 | 114 | NameOccurrence occurrence = (NameOccurrence) k.next();
89 | 114 | if (occurrence.isOnLeftHandSide()) {
90 | 64 | this.addVariableAccess(occurrence.getLocation().getBeginLine(), new VariableAccess(VariableAccess.DEFINITION, occurrence.getImage()), inode.getFlow());
91 | 50 | } else if (occurrence.isOnRightHandSide() || (!occurrence.isOnLeftHandSide() && !occurrence.isOnRightHandSide())) {
92 | 50 | this.addVariableAccess(occurrence.getLocation().getBeginLine(), new VariableAccess(VariableAccess.REFERENCING, occurrence.getImage()), inode.getFlow());
93 |  | }
94 |  | }
95 |  |
96 | 152 | private void addVariableAccess(int line, VariableAccess va, List flow) {
97 | 152 | for (int i = 1; i < flow.size(); i++) {
98 | 1278 | IDataFlowNode inode = (IDataFlowNode) flow.get(i);
99 | 1278 | if (line == inode.getLine()) {
100 | 267 | Vector v = new Vector();
101 | 267 | v.add(va);
102 | 267 | inode.setVariableAccess(v);
103 |  | }
104 |  | }
105 |  | }
106 |  |
107 |  | }