Clover coverage report - PMD - 3.7
Coverage timestamp: Wed May 31 2006 09:25:59 EDT
file stats: LOC: 303   Methods: 8
NCLOC: 186   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
Linker.java 82% 88.7% 100% 87.4%
coverage coverage
 1    /*
 2    * Created on 12.07.2004
 3    */
 4    package net.sourceforge.pmd.dfa;
 5   
 6    import java.util.List;
 7   
 8    /**
 9    * @author raik
 10    * Links data flow nodes to each other.
 11    */
 12    public class Linker {
 13   
 14    private List braceStack;
 15    private List continueBreakReturnStack;
 16   
 17  40 public Linker(List braceStack, List continueBreakReturnStack) {
 18  40 this.braceStack = braceStack;
 19  40 this.continueBreakReturnStack = continueBreakReturnStack;
 20    }
 21   
 22    /**
 23    * Creates all the links between the data flow nodes.
 24    */
 25  40 public void computePaths() throws LinkerException, SequenceException {
 26    // Returns true if there are more sequences, computes the first and
 27    // the last index of the sequence.
 28  40 SequenceChecker sc = new SequenceChecker(braceStack);
 29  40 while (!sc.run()) {
 30  58 if (sc.getFirstIndex() < 0 || sc.getLastIndex() < 0) {
 31  0 throw new SequenceException("computePaths(): return index < 0");
 32    }
 33   
 34  58 StackObject firstStackObject = (StackObject) braceStack.get(sc.getFirstIndex());
 35   
 36  58 switch (firstStackObject.getType()) {
 37  24 case NodeType.IF_EXPR:
 38  24 int x = sc.getLastIndex() - sc.getFirstIndex();
 39  24 if (x == 2) {
 40  11 this.computeIf(sc.getFirstIndex(), sc.getFirstIndex() + 1, sc.getLastIndex());
 41  13 } else if (x == 1) {
 42  13 this.computeIf(sc.getFirstIndex(), sc.getLastIndex());
 43    } else {
 44  0 System.out.println("Error - computePaths 1");
 45    }
 46  24 break;
 47   
 48  3 case NodeType.WHILE_EXPR:
 49  3 this.computeWhile(sc.getFirstIndex(), sc.getLastIndex());
 50  3 break;
 51   
 52  3 case NodeType.SWITCH_START:
 53  3 this.computeSwitch(sc.getFirstIndex(), sc.getLastIndex());
 54  3 break;
 55   
 56  20 case NodeType.FOR_INIT:
 57  5 case NodeType.FOR_EXPR:
 58  0 case NodeType.FOR_UPDATE:
 59  0 case NodeType.FOR_BEFORE_FIRST_STATEMENT:
 60  25 this.computeFor(sc.getFirstIndex(), sc.getLastIndex());
 61  25 break;
 62   
 63  3 case NodeType.DO_BEFORE_FIRST_STATEMENT:
 64  3 this.computeDo(sc.getFirstIndex(), sc.getLastIndex());
 65  3 break;
 66   
 67  0 default:
 68    }
 69   
 70  58 for (int y = sc.getLastIndex(); y >= sc.getFirstIndex(); y--) {
 71  197 braceStack.remove(y);
 72    }
 73    }
 74   
 75  40 while (!continueBreakReturnStack.isEmpty()) {
 76  6 StackObject stackObject = (StackObject) continueBreakReturnStack.get(0);
 77  6 IDataFlowNode node = stackObject.getDataFlowNode();
 78   
 79  6 switch (stackObject.getType()) {
 80  0 case NodeType.RETURN_STATEMENT:
 81    // remove all children (should contain only one child)
 82  0 node.removePathToChild((IDataFlowNode) node.getChildren().get(0));
 83  0 IDataFlowNode lastNode = (IDataFlowNode) node.getFlow().get(node.getFlow().size() - 1);
 84  0 node.addPathToChild(lastNode);
 85  0 continueBreakReturnStack.remove(0);
 86  0 break;
 87  5 case NodeType.BREAK_STATEMENT:
 88    // What about breaks to labels above if statements?
 89  5 List bList = node.getFlow();
 90  8 for (int i = bList.indexOf(node); i < bList.size(); i++) {
 91  8 IDataFlowNode n = (IDataFlowNode) bList.get(i);
 92  8 if (n.isType(NodeType.WHILE_LAST_STATEMENT) ||
 93    n.isType(NodeType.SWITCH_END) ||
 94    n.isType(NodeType.FOR_END) ||
 95    n.isType(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE) ||
 96    n.isType(NodeType.DO_EXPR)) {
 97  5 node.removePathToChild((IDataFlowNode) node.getChildren().get(0));
 98  5 IDataFlowNode last = (IDataFlowNode) bList.get(i + 1);
 99  5 node.addPathToChild(last);
 100  5 continueBreakReturnStack.remove(0);
 101  5 break;
 102    }
 103    }
 104  5 break;
 105   
 106  1 case NodeType.CONTINUE_STATEMENT:
 107    //List cList = node.getFlow();
 108    /* traverse up the tree and find the first loop start node
 109    */
 110    /*
 111    for(int i = cList.indexOf(node)-1;i>=0;i--) {
 112    IDataFlowNode n = (IDataFlowNode)cList.get(i);
 113   
 114    if(n.isType(NodeType.FOR_UPDATE) ||
 115    n.isType(NodeType.FOR_EXPR) ||
 116    n.isType(NodeType.WHILE_EXPR)) {
 117    */
 118    /*
 119    * while(..) {
 120    * while(...) {
 121    * ...
 122    * }
 123    * continue;
 124    * }
 125    *
 126    * Without this Expression he continues the second
 127    * WHILE loop. The continue statement and the while loop
 128    * have to be in different scopes.
 129    *
 130    * TODO An error occurs if "continue" is even nested in
 131    * scopes other than local loop scopes, like "if".
 132    * The result is, that the data flow isn't build right
 133    * and the pathfinder runs in invinity loop.
 134    * */
 135    /* if(n.getSimpleNode().getScope().equals(node.getSimpleNode().getScope())) {
 136    System.err.println("equals");
 137    continue;
 138    }
 139    else {
 140    System.err.println("don't equals");
 141    }
 142   
 143    //remove all children (should contain only one child)
 144    node.removePathToChild((IDataFlowNode)node.getChildren().get(0));
 145   
 146    node.addPathToChild(n);
 147    cbrStack.remove(0);
 148    break;
 149   
 150    }else if(n.isType(NodeType.DO_BEFOR_FIRST_STATEMENT)) {
 151   
 152    IDataFlowNode inode = (IDataFlowNode)n.getFlow().get(n.getIndex()1);
 153   
 154    for(int j=0;j<inode.getParents().size();j) {
 155    IDataFlowNode parent = (IDataFlowNode)inode.getParents().get(j);
 156   
 157    if(parent.isType(NodeType.DO_EXPR)) {
 158    node.removePathToChild((IDataFlowNode)node.getChildren().get(0));
 159    node.addPathToChild(parent);
 160   
 161    cbrStack.remove(0);
 162    break;
 163    }
 164    }
 165    break;
 166    }
 167    }
 168  1 */continueBreakReturnStack.remove(0); // delete this statement if you uncomment the stuff above
 169    }
 170    }
 171    }
 172   
 173  3 private void computeDo(int first, int last) {
 174  3 IDataFlowNode doSt = ((StackObject) this.braceStack.get(first)).getDataFlowNode();
 175  3 IDataFlowNode doExpr = ((StackObject) this.braceStack.get(last)).getDataFlowNode();
 176    //IDataFlowNode doFirst = (IDataFlowNode)doSt.getChildren().get(0);
 177  3 IDataFlowNode doFirst = (IDataFlowNode) doSt.getFlow().get(doSt.getIndex() + 1);
 178  3 if (doFirst.getIndex() != doExpr.getIndex()) {
 179  3 doExpr.addPathToChild(doFirst);
 180    }
 181    }
 182   
 183  25 private void computeFor(int firstIndex, int lastIndex) {
 184  25 IDataFlowNode fExpr = null;
 185  25 IDataFlowNode fUpdate = null;
 186  25 IDataFlowNode fSt = null;
 187  25 IDataFlowNode fEnd = null;
 188  25 boolean isUpdate = false;
 189   
 190  25 for (int i = firstIndex; i <= lastIndex; i++) {
 191  115 StackObject so = (StackObject) this.braceStack.get(i);
 192  115 IDataFlowNode node = so.getDataFlowNode();
 193   
 194  115 if (so.getType() == NodeType.FOR_EXPR) {
 195  25 fExpr = node;
 196  90 } else if (so.getType() == NodeType.FOR_UPDATE) {
 197  20 fUpdate = node;
 198  20 isUpdate = true;
 199  70 } else if (so.getType() == NodeType.FOR_BEFORE_FIRST_STATEMENT) {
 200  25 fSt = node;
 201  45 } else if (so.getType() == NodeType.FOR_END) {
 202  25 fEnd = node;
 203    }
 204    }
 205  25 IDataFlowNode end = (IDataFlowNode) fEnd.getFlow().get(fEnd.getIndex() + 1);
 206   
 207  25 IDataFlowNode firstSt = (IDataFlowNode) fSt.getChildren().get(0);
 208   
 209  25 if (isUpdate) {
 210  20 if (fSt.getIndex() != fEnd.getIndex()) {
 211  14 end.reverseParentPathsTo(fUpdate);
 212  14 fExpr.removePathToChild(fUpdate);
 213  14 fUpdate.addPathToChild(fExpr);
 214  14 fUpdate.removePathToChild(firstSt);
 215  14 fExpr.addPathToChild(firstSt);
 216  14 fExpr.addPathToChild(end);
 217    } else {
 218  6 fSt.removePathToChild(end);
 219  6 fExpr.removePathToChild(fUpdate);
 220  6 fUpdate.addPathToChild(fExpr);
 221  6 fExpr.addPathToChild(fUpdate);
 222  6 fExpr.addPathToChild(end);
 223    }
 224    } else {
 225  5 if (fSt.getIndex() != fEnd.getIndex()) {
 226  1 end.reverseParentPathsTo(fExpr);
 227  1 fExpr.addPathToChild(end);
 228    }
 229    }
 230    }
 231   
 232  3 private void computeSwitch(int firstIndex, int lastIndex) {
 233   
 234  3 int diff = lastIndex - firstIndex;
 235  3 boolean defaultStatement = false;
 236   
 237  3 IDataFlowNode sStart = ((StackObject) this.braceStack.get(firstIndex)).getDataFlowNode();
 238  3 IDataFlowNode sEnd = ((StackObject) this.braceStack.get(lastIndex)).getDataFlowNode();
 239  3 IDataFlowNode end = (IDataFlowNode) sEnd.getChildren().get(0);
 240   
 241  3 for (int i = 0; i < diff - 2; i++) {
 242  2 StackObject so = (StackObject) this.braceStack.get(firstIndex + 2 + i);
 243  2 IDataFlowNode node = so.getDataFlowNode();
 244   
 245  2 sStart.addPathToChild((IDataFlowNode) node.getChildren().get(0));
 246   
 247  2 if (so.getType() == NodeType.SWITCH_LAST_DEFAULT_STATEMENT)
 248  1 defaultStatement = true;
 249    }
 250   
 251  3 if (!defaultStatement)
 252  2 sStart.addPathToChild(end);
 253    }
 254   
 255  3 private void computeWhile(int first, int last) {
 256  3 IDataFlowNode wStart = ((StackObject) this.braceStack.get(first)).getDataFlowNode();
 257  3 IDataFlowNode wEnd = ((StackObject) this.braceStack.get(last)).getDataFlowNode();
 258   
 259  3 IDataFlowNode end = (IDataFlowNode) wEnd.getFlow().get(wEnd.getIndex() + 1);
 260   
 261  3 if (wStart.getIndex() != wEnd.getIndex()) {
 262  2 end.reverseParentPathsTo(wStart);
 263  2 wStart.addPathToChild(end);
 264    }
 265    }
 266   
 267  11 private void computeIf(int first, int second, int last) {
 268  11 IDataFlowNode ifStart = ((StackObject) this.braceStack.get(first)).getDataFlowNode();
 269  11 IDataFlowNode ifEnd = ((StackObject) this.braceStack.get(second)).getDataFlowNode();
 270  11 IDataFlowNode elseEnd = ((StackObject) this.braceStack.get(last)).getDataFlowNode();
 271   
 272  11 IDataFlowNode elseStart = (IDataFlowNode) ifEnd.getFlow().get(ifEnd.getIndex() + 1);
 273  11 IDataFlowNode end = (IDataFlowNode) elseEnd.getFlow().get(elseEnd.getIndex() + 1);
 274   
 275    // if if-statement and else-statement contains statements or expressions
 276  11 if (ifStart.getIndex() != ifEnd.getIndex() &&
 277    ifEnd.getIndex() != elseEnd.getIndex()) {
 278  11 elseStart.reverseParentPathsTo(end);
 279  11 ifStart.addPathToChild(elseStart);
 280    }
 281    // if only if-statement contains no expressions
 282  0 else if (ifStart.getIndex() == ifEnd.getIndex() &&
 283    ifEnd.getIndex() != elseEnd.getIndex()) {
 284  0 ifStart.addPathToChild(end);
 285    }
 286    // if only else-statement contains no expressions
 287  0 else if (ifEnd.getIndex() == elseEnd.getIndex() &&
 288    ifStart.getIndex() != ifEnd.getIndex()) {
 289  0 ifStart.addPathToChild(end);
 290    }
 291    }
 292   
 293  13 private void computeIf(int first, int last) {
 294  13 IDataFlowNode ifStart = ((StackObject) this.braceStack.get(first)).getDataFlowNode();
 295  13 IDataFlowNode ifEnd = ((StackObject) this.braceStack.get(last)).getDataFlowNode();
 296   
 297    // only if the if-statement contains another Statement or Expression
 298  13 if (ifStart.getIndex() != ifEnd.getIndex()) {
 299  12 IDataFlowNode end = (IDataFlowNode) ifEnd.getFlow().get(ifEnd.getIndex() + 1);
 300  12 ifStart.addPathToChild(end);
 301    }
 302    }
 303    }