1 package net.sourceforge.pmd.dfa; 2 3 import net.sourceforge.pmd.ast.ASTConstructorDeclaration; 4 import net.sourceforge.pmd.ast.ASTMethodDeclaration; 5 import net.sourceforge.pmd.ast.SimpleNode; 6 7 import java.util.ArrayList ; 8 import java.util.BitSet ; 9 import java.util.HashMap ; 10 import java.util.LinkedList ; 11 import java.util.List ; 12 import java.util.Map ; 13 import java.util.StringTokenizer ; 14 15 20 public class DataFlowNode implements IDataFlowNode { 21 22 private SimpleNode node; 23 private Map typeMap = new HashMap (); 24 25 protected List parents = new ArrayList (); 26 protected List children = new ArrayList (); 27 protected BitSet type = new BitSet (); 28 protected List variableAccess = new ArrayList (); 29 protected LinkedList dataFlow; 30 protected int line; 31 32 protected DataFlowNode() { 33 } 34 35 public DataFlowNode(SimpleNode node, LinkedList dataFlow) { 36 this.dataFlow = dataFlow; 37 this.node = node; 38 39 node.setDataFlowNode(this); 40 this.line = node.getBeginLine(); 41 42 if (!this.dataFlow.isEmpty()) { 43 DataFlowNode parent = (DataFlowNode) this.dataFlow.getLast(); 44 parent.addPathToChild(this); 45 } 46 this.dataFlow.addLast(this); 47 } 48 49 public void addPathToChild(IDataFlowNode child) { 50 DataFlowNode thisChild = (DataFlowNode) child; 51 if (!this.children.contains(thisChild) || this.equals(thisChild)) { 53 this.children.add(thisChild); 54 thisChild.parents.add(this); 55 } 56 } 57 58 public boolean removePathToChild(IDataFlowNode child) { 59 DataFlowNode thisChild = (DataFlowNode) child; 60 thisChild.parents.remove(this); 61 return this.children.remove(thisChild); 62 } 63 64 public void reverseParentPathsTo(IDataFlowNode destination) { 65 while (!parents.isEmpty()) { 66 DataFlowNode parent = (DataFlowNode) parents.get(0); 67 parent.removePathToChild(this); 68 parent.addPathToChild(destination); 69 } 70 } 71 72 public int getLine() { 73 return this.line; 74 } 75 76 public void setType(int type) { 77 this.type.set(type); 78 } 79 80 public boolean isType(int intype) { 81 try { 82 return type.get(intype); 83 } catch (IndexOutOfBoundsException e) { 84 e.printStackTrace(); 85 } 86 return false; 87 } 88 89 public SimpleNode getSimpleNode() { 90 return this.node; 91 } 92 93 public List getChildren() { 94 return this.children; 95 } 96 97 public List getParents() { 98 return this.parents; 99 } 100 101 public List getFlow() { 102 return this.dataFlow; 103 } 104 105 public int getIndex() { 106 return this.dataFlow.indexOf(this); 107 } 108 109 public void setVariableAccess(List variableAccess) { 110 if (this.variableAccess.isEmpty()) { 111 this.variableAccess = variableAccess; 112 } else { 113 this.variableAccess.addAll(variableAccess); 114 } 115 } 116 117 public List getVariableAccess() { 118 return this.variableAccess; 119 } 120 121 public String toString() { 122 String res = "DataFlowNode: line " + this.getLine() + ", "; 123 if (node instanceof ASTMethodDeclaration || node instanceof ASTConstructorDeclaration) { 124 res += (node instanceof ASTMethodDeclaration) ? "(method)" : "(constructor)"; 125 } else { 126 String tmp = type.toString(); 127 String newTmp = ""; 128 for (int i = 0; i < tmp.length(); i++) { 129 if (tmp.charAt(i) != '{' && tmp.charAt(i) != '}' && tmp.charAt(i) != ' ') { 130 newTmp += tmp.charAt(i); 131 } 132 } 133 for (StringTokenizer st = new StringTokenizer (newTmp, ","); st.hasMoreTokens();) { 134 int newTmpInt = Integer.parseInt(st.nextToken()); 135 res += "(" + stringFromType(newTmpInt) + ")"; 136 } 137 res += ", " + this.node.getClass().getName().substring(node.getClass().getName().lastIndexOf('.') + 1); 138 res += (node.getImage() == null ? "" : "(" + this.node.getImage() + ")"); 139 } 140 return res; 141 } 142 143 private String stringFromType(int intype) { 144 if (typeMap.isEmpty()) { 145 typeMap.put(new Integer (NodeType.IF_EXPR), "IF_EXPR"); 146 typeMap.put(new Integer (NodeType.IF_LAST_STATEMENT), "IF_LAST_STATEMENT"); 147 typeMap.put(new Integer (NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE), "IF_LAST_STATEMENT_WITHOUT_ELSE"); 148 typeMap.put(new Integer (NodeType.ELSE_LAST_STATEMENT), "ELSE_LAST_STATEMENT"); 149 typeMap.put(new Integer (NodeType.WHILE_LAST_STATEMENT), "WHILE_LAST_STATEMENT"); 150 typeMap.put(new Integer (NodeType.WHILE_EXPR), "WHILE_EXPR"); 151 typeMap.put(new Integer (NodeType.SWITCH_START), "SWITCH_START"); 152 typeMap.put(new Integer (NodeType.CASE_LAST_STATEMENT), "CASE_LAST_STATEMENT"); 153 typeMap.put(new Integer (NodeType.SWITCH_LAST_DEFAULT_STATEMENT), "SWITCH_LAST_DEFAULT_STATEMENT"); 154 typeMap.put(new Integer (NodeType.SWITCH_END), "SWITCH_END"); 155 typeMap.put(new Integer (NodeType.FOR_INIT), "FOR_INIT"); 156 typeMap.put(new Integer (NodeType.FOR_EXPR), "FOR_EXPR"); 157 typeMap.put(new Integer (NodeType.FOR_UPDATE), "FOR_UPDATE"); 158 typeMap.put(new Integer (NodeType.FOR_BEFORE_FIRST_STATEMENT), "FOR_BEFORE_FIRST_STATEMENT"); 159 typeMap.put(new Integer (NodeType.FOR_END), "FOR_END"); 160 typeMap.put(new Integer (NodeType.DO_BEFORE_FIRST_STATEMENT), "DO_BEFORE_FIRST_STATEMENT"); 161 typeMap.put(new Integer (NodeType.DO_EXPR), "DO_EXPR"); 162 typeMap.put(new Integer (NodeType.RETURN_STATEMENT), "RETURN_STATEMENT"); 163 typeMap.put(new Integer (NodeType.BREAK_STATEMENT), "BREAK_STATEMENT"); 164 typeMap.put(new Integer (NodeType.CONTINUE_STATEMENT), "CONTINUE_STATEMENT"); 165 typeMap.put(new Integer (NodeType.LABEL_STATEMENT), "LABEL_STATEMENT"); 166 typeMap.put(new Integer (NodeType.LABEL_LAST_STATEMENT), "LABEL_END"); 167 } 168 if (!typeMap.containsKey(new Integer (intype))) { 169 throw new RuntimeException ("Couldn't find type id " + intype); 170 } 171 return (String ) typeMap.get(new Integer (intype)); 172 } 173 174 } 175 | Popular Tags |