1 4 package net.sourceforge.pmd.dfa; 5 6 import net.sourceforge.pmd.ast.*; 7 8 15 public class StatementAndBraceFinder extends JavaParserVisitorAdapter { 16 17 private Structure dataFlow; 18 19 public void buildDataFlowFor(SimpleJavaNode node) { 20 if (!(node instanceof ASTMethodDeclaration) && !(node instanceof ASTConstructorDeclaration)) { 21 throw new RuntimeException ("Can't build a data flow for anything other than a method or a constructor"); 22 } 23 24 this.dataFlow = new Structure(); 25 this.dataFlow.createStartNode(node.getBeginLine()); 26 this.dataFlow.createNewNode(node); 27 28 node.jjtAccept(this, dataFlow); 29 30 this.dataFlow.createEndNode(node.getEndLine()); 31 32 Linker linker = new Linker(dataFlow.getBraceStack(), dataFlow.getContinueBreakReturnStack()); 33 try { 34 linker.computePaths(); 35 } catch (LinkerException e) { 36 e.printStackTrace(); 37 } catch (SequenceException e) { 38 e.printStackTrace(); 39 } 40 } 41 42 public Object visit(ASTStatementExpression node, Object data) { 43 if (!(data instanceof Structure)) { 44 return data; 45 } 46 Structure dataFlow = (Structure) data; 47 dataFlow.createNewNode(node); 48 return super.visit(node, data); 49 } 50 51 public Object visit(ASTVariableDeclarator node, Object data) { 52 if (!(data instanceof Structure)) { 53 return data; 54 } 55 Structure dataFlow = (Structure) data; 56 dataFlow.createNewNode(node); 57 return super.visit(node, data); 58 } 59 60 public Object visit(ASTExpression node, Object data) { 61 if (!(data instanceof Structure)) { 62 return data; 63 } 64 Structure dataFlow = (Structure) data; 65 66 if (node.jjtGetParent() instanceof ASTIfStatement) { 68 dataFlow.createNewNode(node); dataFlow.pushOnStack(NodeType.IF_EXPR, dataFlow.getLast()); 70 } else if (node.jjtGetParent() instanceof ASTWhileStatement) { 71 dataFlow.createNewNode(node); dataFlow.pushOnStack(NodeType.WHILE_EXPR, dataFlow.getLast()); 73 } else if (node.jjtGetParent() instanceof ASTSwitchStatement) { 74 dataFlow.createNewNode(node); dataFlow.pushOnStack(NodeType.SWITCH_START, dataFlow.getLast()); 76 } else if (node.jjtGetParent() instanceof ASTForStatement) { 77 dataFlow.createNewNode(node); dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast()); 79 } else if (node.jjtGetParent() instanceof ASTDoStatement) { 80 dataFlow.createNewNode(node); dataFlow.pushOnStack(NodeType.DO_EXPR, dataFlow.getLast()); 82 } 83 84 return super.visit(node, data); 85 } 86 87 public Object visit(ASTForInit node, Object data) { 88 if (!(data instanceof Structure)) { 89 return data; 90 } 91 Structure dataFlow = (Structure) data; 92 super.visit(node, data); 93 dataFlow.pushOnStack(NodeType.FOR_INIT, dataFlow.getLast()); 94 this.addForExpressionNode(node, dataFlow); 95 return data; 96 } 97 98 public Object visit(ASTLabeledStatement node, Object data) { 99 dataFlow.createNewNode(node); 100 dataFlow.pushOnStack(NodeType.LABEL_STATEMENT, dataFlow.getLast()); 101 return super.visit(node, data); 102 } 103 104 public Object visit(ASTForUpdate node, Object data) { 105 if (!(data instanceof Structure)) { 106 return data; 107 } 108 Structure dataFlow = (Structure) data; 109 this.addForExpressionNode(node, dataFlow); 110 super.visit(node, data); 111 dataFlow.pushOnStack(NodeType.FOR_UPDATE, dataFlow.getLast()); 112 return data; 113 } 114 115 118 public Object visit(ASTStatement node, Object data) { 119 if (!(data instanceof Structure)) { 120 return data; 121 } 122 Structure dataFlow = (Structure) data; 123 124 if (node.jjtGetParent() instanceof ASTForStatement) { 125 this.addForExpressionNode(node, dataFlow); 126 dataFlow.pushOnStack(NodeType.FOR_BEFORE_FIRST_STATEMENT, dataFlow.getLast()); 127 } else if (node.jjtGetParent() instanceof ASTDoStatement) { 128 dataFlow.pushOnStack(NodeType.DO_BEFORE_FIRST_STATEMENT, dataFlow.getLast()); 129 dataFlow.createNewNode((SimpleNode) node.jjtGetParent()); 130 } 131 132 super.visit(node, data); 133 134 if (node.jjtGetParent() instanceof ASTIfStatement) { 135 ASTIfStatement st = (ASTIfStatement) node.jjtGetParent(); 136 if (!st.hasElse()) { 137 dataFlow.pushOnStack(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, dataFlow.getLast()); 138 } else if (st.hasElse() && !st.jjtGetChild(1).equals(node)) { 139 dataFlow.pushOnStack(NodeType.ELSE_LAST_STATEMENT, dataFlow.getLast()); 140 } else { 141 dataFlow.pushOnStack(NodeType.IF_LAST_STATEMENT, dataFlow.getLast()); 142 } 143 } else if (node.jjtGetParent() instanceof ASTWhileStatement) { 144 dataFlow.pushOnStack(NodeType.WHILE_LAST_STATEMENT, dataFlow.getLast()); 145 } else if (node.jjtGetParent() instanceof ASTForStatement) { 146 dataFlow.pushOnStack(NodeType.FOR_END, dataFlow.getLast()); 147 } else if (node.jjtGetParent() instanceof ASTLabeledStatement) { 148 dataFlow.pushOnStack(NodeType.LABEL_LAST_STATEMENT, dataFlow.getLast()); 149 } 150 return data; 151 } 152 153 public Object visit(ASTSwitchStatement node, Object data) { 154 if (!(data instanceof Structure)) { 155 return data; 156 } 157 Structure dataFlow = (Structure) data; 158 super.visit(node, data); 159 dataFlow.pushOnStack(NodeType.SWITCH_END, dataFlow.getLast()); 160 return data; 161 } 162 163 public Object visit(ASTSwitchLabel node, Object data) { 164 if (!(data instanceof Structure)) { 165 return data; 166 } 167 Structure dataFlow = (Structure) data; 168 if (node.jjtGetNumChildren() == 0) { 170 dataFlow.pushOnStack(NodeType.SWITCH_LAST_DEFAULT_STATEMENT, dataFlow.getLast()); 171 } else { 172 dataFlow.pushOnStack(NodeType.CASE_LAST_STATEMENT, dataFlow.getLast()); 173 } 174 return data; 175 } 176 177 public Object visit(ASTBreakStatement node, Object data) { 178 if (!(data instanceof Structure)) { 179 return data; 180 } 181 Structure dataFlow = (Structure) data; 182 dataFlow.createNewNode(node); 183 dataFlow.pushOnStack(NodeType.BREAK_STATEMENT, dataFlow.getLast()); 184 return super.visit(node, data); 185 } 186 187 188 public Object visit(ASTContinueStatement node, Object data) { 189 if (!(data instanceof Structure)) { 190 return data; 191 } 192 Structure dataFlow = (Structure) data; 193 dataFlow.createNewNode(node); 194 dataFlow.pushOnStack(NodeType.CONTINUE_STATEMENT, dataFlow.getLast()); 195 return super.visit(node, data); 196 } 197 198 public Object visit(ASTReturnStatement node, Object data) { 199 if (!(data instanceof Structure)) { 200 return data; 201 } 202 Structure dataFlow = (Structure) data; 203 dataFlow.createNewNode(node); 204 dataFlow.pushOnStack(NodeType.RETURN_STATEMENT, dataFlow.getLast()); 205 return super.visit(node, data); 206 } 207 208 212 private void addForExpressionNode(SimpleNode node, Structure dataFlow) { 213 ASTForStatement parent = (ASTForStatement) node.jjtGetParent(); 214 boolean hasExpressionChild = false; 215 boolean hasForInitNode = false; 216 boolean hasForUpdateNode = false; 217 218 for (int i = 0; i < parent.jjtGetNumChildren(); i++) { 219 if (parent.jjtGetChild(i) instanceof ASTExpression) 220 hasExpressionChild = true; 221 else if (parent.jjtGetChild(i) instanceof ASTForUpdate) 222 hasForUpdateNode = true; 223 else if (parent.jjtGetChild(i) instanceof ASTForInit) 224 hasForInitNode = true; 225 } 226 if (!hasExpressionChild) { 227 if (node instanceof ASTForInit) { 228 dataFlow.createNewNode(node); 229 dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast()); 230 } else if (node instanceof ASTForUpdate) { 231 if (!hasForInitNode) { 232 dataFlow.createNewNode(node); 233 dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast()); 234 } 235 } else if (node instanceof ASTStatement) { 236 if (!hasForInitNode && !hasForUpdateNode) { 237 dataFlow.createNewNode(node); 238 dataFlow.pushOnStack(NodeType.FOR_EXPR, dataFlow.getLast()); 239 } 240 } 241 } 242 } 243 } 244 | Popular Tags |