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