View Javadoc

1   /**
2    * BSD-style license; for more info see http://pmd.sourceforge.net/license.html
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   * @author raik
17   *         <p/>
18   *         Each data flow contains a set of DataFlowNodes.
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  	// TODO - throw an exception if already contained in children list?
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 }