1
2
3
4 package net.sourceforge.pmd.lang.dfa;
5
6 import java.util.ArrayList;
7 import java.util.BitSet;
8 import java.util.HashMap;
9 import java.util.List;
10 import java.util.Map;
11 import java.util.StringTokenizer;
12
13 import net.sourceforge.pmd.lang.ast.Node;
14
15
16
17
18
19
20 public abstract class AbstractDataFlowNode implements DataFlowNode {
21
22 protected Node node;
23
24 protected List<DataFlowNode> parents = new ArrayList<DataFlowNode>();
25 protected List<DataFlowNode> children = new ArrayList<DataFlowNode>();
26 protected BitSet type = new BitSet();
27 protected List<VariableAccess> variableAccess = new ArrayList<VariableAccess>();
28 protected List<DataFlowNode> dataFlow;
29 protected int line;
30
31 public AbstractDataFlowNode(List<DataFlowNode> dataFlow) {
32 this.dataFlow = dataFlow;
33 if (!this.dataFlow.isEmpty()) {
34 DataFlowNode parent = this.dataFlow.get(this.dataFlow.size() - 1);
35 parent.addPathToChild(this);
36 }
37 this.dataFlow.add(this);
38 }
39
40 public AbstractDataFlowNode(List<DataFlowNode> dataFlow, Node node) {
41 this(dataFlow);
42
43 this.node = node;
44 node.setDataFlowNode(this);
45 this.line = node.getBeginLine();
46 }
47
48 public void addPathToChild(DataFlowNode child) {
49 DataFlowNode thisChild = child;
50
51 if (!this.children.contains(thisChild) || this.equals(thisChild)) {
52 this.children.add(thisChild);
53 thisChild.getParents().add(this);
54 }
55 }
56
57 public boolean removePathToChild(DataFlowNode child) {
58 DataFlowNode thisChild = child;
59 thisChild.getParents().remove(this);
60 return this.children.remove(thisChild);
61 }
62
63 public void reverseParentPathsTo(DataFlowNode destination) {
64 while (!parents.isEmpty()) {
65 DataFlowNode parent = parents.get(0);
66 parent.removePathToChild(this);
67 parent.addPathToChild(destination);
68 }
69 }
70
71 public int getLine() {
72 return this.line;
73 }
74
75 public void setType(int type) {
76 this.type.set(type);
77 }
78
79 public boolean isType(int intype) {
80 try {
81 return type.get(intype);
82 } catch (IndexOutOfBoundsException e) {
83 e.printStackTrace();
84 }
85 return false;
86 }
87
88 public Node getNode() {
89 return this.node;
90 }
91
92 public List<DataFlowNode> getChildren() {
93 return this.children;
94 }
95
96 public List<DataFlowNode> getParents() {
97 return this.parents;
98 }
99
100 public List<DataFlowNode> getFlow() {
101 return this.dataFlow;
102 }
103
104 public int getIndex() {
105 return this.dataFlow.indexOf(this);
106 }
107
108 public void setVariableAccess(List<VariableAccess> variableAccess) {
109 if (this.variableAccess.isEmpty()) {
110 this.variableAccess = variableAccess;
111 } else {
112 this.variableAccess.addAll(variableAccess);
113 }
114 }
115
116 public List<VariableAccess> getVariableAccess() {
117 return this.variableAccess;
118 }
119
120 @Override
121 public String toString() {
122 String res = "DataFlowNode: line " + this.getLine() + ", ";
123 String tmp = type.toString();
124 String newTmp = "";
125 for (char c : tmp.toCharArray()) {
126 if (c != '{' && c != '}' && c != ' ') {
127 newTmp += c;
128 }
129 }
130 for (StringTokenizer st = new StringTokenizer(newTmp, ","); st.hasMoreTokens();) {
131 int newTmpInt = Integer.parseInt(st.nextToken());
132 res += "(" + stringFromType(newTmpInt) + ")";
133 }
134 res += ", " + this.node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.') + 1);
135 res += node.getImage() == null ? "" : "(" + this.node.getImage() + ")";
136 return res;
137 }
138
139 private String stringFromType(int intype) {
140 return NodeType.stringFromType(intype) ;
141 }
142
143 }