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