1 4 package net.sourceforge.pmd.dfa; 5 6 import java.util.ArrayList ; 7 import java.util.List ; 8 9 23 public class SequenceChecker { 24 25 28 private static class Status { 29 public static final int ROOT = -1; 30 31 private List nextSteps = new ArrayList (); 32 private int type; 33 private boolean lastStep; 34 35 36 public Status(int type) { 37 this(type, false); 38 } 39 40 public Status(int type, boolean lastStep) { 41 this.type = type; 42 this.lastStep = lastStep; 43 } 44 45 public void addStep(Status type) { 46 nextSteps.add(type); 47 } 48 49 public Status step(int type) { 50 for (int i = 0; i < this.nextSteps.size(); i++) { 51 if (type == ((Status) nextSteps.get(i)).type) { 52 return (Status) nextSteps.get(i); 53 } 54 } 55 return null; 56 } 57 58 public boolean isLastStep() { 59 return this.lastStep; 60 } 61 62 public boolean hasMoreSteps() { 63 return this.nextSteps.size() > 1; 64 } 65 } 66 67 private static Status root; 68 69 static { 70 root = new Status(Status.ROOT); 71 Status ifNode = new Status(NodeType.IF_EXPR); 72 Status ifSt = new Status(NodeType.IF_LAST_STATEMENT); 73 Status ifStWithoutElse = new Status(NodeType.IF_LAST_STATEMENT_WITHOUT_ELSE, true); 74 Status elseSt = new Status(NodeType.ELSE_LAST_STATEMENT, true); 75 Status whileNode = new Status(NodeType.WHILE_EXPR); 76 Status whileSt = new Status(NodeType.WHILE_LAST_STATEMENT, true); 77 Status switchNode = new Status(NodeType.SWITCH_START); 78 Status caseSt = new Status(NodeType.CASE_LAST_STATEMENT); 79 Status switchDefault = new Status(NodeType.SWITCH_LAST_DEFAULT_STATEMENT); 80 Status switchEnd = new Status(NodeType.SWITCH_END, true); 81 82 Status forInit = new Status(NodeType.FOR_INIT); 83 Status forExpr = new Status(NodeType.FOR_EXPR); 84 Status forUpdate = new Status(NodeType.FOR_UPDATE); 85 Status forSt = new Status(NodeType.FOR_BEFORE_FIRST_STATEMENT); 86 Status forEnd = new Status(NodeType.FOR_END, true); 87 88 Status doSt = new Status(NodeType.DO_BEFORE_FIRST_STATEMENT); 89 Status doExpr = new Status(NodeType.DO_EXPR, true); 90 91 Status labelNode = new Status(NodeType.LABEL_STATEMENT); 92 Status labelEnd = new Status(NodeType.LABEL_LAST_STATEMENT, true); 93 94 root.addStep(ifNode); 95 root.addStep(whileNode); 96 root.addStep(switchNode); 97 root.addStep(forInit); 98 root.addStep(forExpr); 99 root.addStep(forUpdate); 100 root.addStep(forSt); 101 root.addStep(doSt); 102 root.addStep(labelNode); 103 104 ifNode.addStep(ifSt); 105 ifNode.addStep(ifStWithoutElse); 106 ifSt.addStep(elseSt); 107 ifStWithoutElse.addStep(root); 108 elseSt.addStep(root); 109 110 labelNode.addStep(labelEnd); 111 labelEnd.addStep(root); 112 113 whileNode.addStep(whileSt); 114 whileSt.addStep(root); 115 116 switchNode.addStep(caseSt); 117 switchNode.addStep(switchDefault); 118 switchNode.addStep(switchEnd); 119 caseSt.addStep(caseSt); 120 caseSt.addStep(switchDefault); 121 caseSt.addStep(switchEnd); 122 switchDefault.addStep(switchEnd); 123 switchDefault.addStep(caseSt); 124 switchEnd.addStep(root); 125 126 forInit.addStep(forExpr); 127 forInit.addStep(forUpdate); 128 forInit.addStep(forSt); 129 forExpr.addStep(forUpdate); 130 forExpr.addStep(forSt); 131 forUpdate.addStep(forSt); 132 forSt.addStep(forEnd); 133 forEnd.addStep(root); 134 135 doSt.addStep(doExpr); 136 doExpr.addStep(root); 137 } 138 139 private Status aktStatus; 140 private List bracesList; 141 142 private int firstIndex = -1; 143 private int lastIndex = -1; 144 145 148 public SequenceChecker(List bracesList) { 149 this.aktStatus = root; 150 this.bracesList = bracesList; 151 } 152 153 157 public boolean run() { 158 this.aktStatus = root; 159 this.firstIndex = 0; 160 this.lastIndex = 0; 161 boolean lookAhead = false; 162 163 for (int i = 0; i < this.bracesList.size(); i++) { 164 StackObject so = (StackObject) bracesList.get(i); 165 aktStatus = this.aktStatus.step(so.getType()); 166 167 if (aktStatus == null) { 168 if (lookAhead) { 169 this.lastIndex = i - 1; 170 return false; 171 } 172 this.aktStatus = root; 173 this.firstIndex = i; 174 i--; 175 continue; 176 } else { 177 if (aktStatus.isLastStep() && !aktStatus.hasMoreSteps()) { 178 this.lastIndex = i; 179 return false; 180 } else if (aktStatus.isLastStep() && aktStatus.hasMoreSteps()) { 181 lookAhead = true; 182 this.lastIndex = i; 183 } 184 } 185 } 186 return this.firstIndex == this.lastIndex; 187 } 188 189 public int getFirstIndex() { 190 return this.firstIndex; 191 } 192 193 public int getLastIndex() { 194 return this.lastIndex; 195 } 196 197 } 198 | Popular Tags |