Skip to content

Commit 04b9362

Browse files
committed
Refactor routine boundary transitions into focused stages
Signed-off-by: minleejae <mmj9808@gmail.com>
1 parent 65b4764 commit 04b9362

1 file changed

Lines changed: 93 additions & 34 deletions

File tree

‎src/main/java/net/sf/jsqlparser/parser/RoutineBodyBoundary.java‎

Lines changed: 93 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -78,35 +78,61 @@ void accept(Token token, Token next) {
7878
}
7979

8080
private void acceptTopLevel(Token token, Token next) {
81-
int kind = token.kind;
8281
if (afterDot) {
8382
return; // Qualified type/column names may use otherwise significant keywords.
8483
}
8584
// END IF/CASE/LOOP/WHILE/REPEAT is one terminator, not another opener.
86-
if (previousKind == K_END && (kind == K_IF || kind == K_CASE || kind == K_LOOP
87-
|| keyword(token, "WHILE") || keyword(token, "REPEAT"))) {
85+
if (previousKind == K_END && isEndQualifier(token)) {
8886
return;
8987
}
88+
if (!acceptRoutineHeader(token)) {
89+
acceptBodyToken(token, next);
90+
}
91+
}
92+
93+
private boolean acceptRoutineHeader(Token token) {
94+
int kind = token.kind;
9095
if (kind == K_RETURNS && !bodyStarted) {
9196
standardReturns = true;
9297
returnTypeName = true;
93-
return;
98+
return true;
9499
}
95100
if (returnTypeName) {
96101
returnTypeName = keyword(token, "SETOF");
97-
return;
102+
return true;
98103
}
99104
if (!compoundBody && (kind == K_AS || kind == K_IS)
100105
&& (!bodyStarted || statementKind == K_RETURN && !standardReturns
101106
|| statementKind == K_SET)) {
102107
declarations = true;
103108
bodyStarted = false;
109+
return true;
110+
}
111+
return false;
112+
}
113+
114+
private void acceptBodyToken(Token token, Token next) {
115+
int kind = token.kind;
116+
if (acceptStatementBoundary(kind)) {
104117
return;
105118
}
106-
if (kind == ST_SEMICOLON) {
119+
if (!(hasParameters || declarations || bodyStarted)) {
120+
return;
121+
}
122+
if (handlerAction && isSimpleStatementStart(kind)) {
107123
startStatement();
124+
}
125+
if (acceptBeginOrCase(kind) || declarations || acceptControlFlow(token)) {
108126
return;
109127
}
128+
acceptStatementToken(token, next);
129+
}
130+
131+
private boolean acceptStatementBoundary(int kind) {
132+
if (kind == ST_SEMICOLON) {
133+
startStatement();
134+
return true;
135+
}
110136
if (kind == K_END) {
111137
if (!blocks.isEmpty()) {
112138
Block closed = blocks.pop();
@@ -116,22 +142,20 @@ private void acceptTopLevel(Token token, Token next) {
116142
completed = true;
117143
}
118144
statementStart = false;
119-
return;
120-
}
121-
if (!(hasParameters || declarations || bodyStarted)) {
122-
return;
123-
}
124-
if (handlerAction && isSimpleStatementStart(kind)) {
125-
startStatement();
145+
return true;
126146
}
147+
return false;
148+
}
149+
150+
private boolean acceptBeginOrCase(int kind) {
127151
if (kind == K_BEGIN
128152
&& (!bodyStarted || statementStart || statementKind == K_DECLARE)) {
129153
blocks.push(Block.BEGIN);
130154
declarations = false;
131155
compoundBody = true;
132156
bodyStarted = true;
133157
startStatement();
134-
return;
158+
return true;
135159
}
136160
if (kind == K_CASE) {
137161
boolean statementCase = !declarations && (statementStart || handlerAction);
@@ -142,44 +166,56 @@ private void acceptTopLevel(Token token, Token next) {
142166
handlerAction = false;
143167
}
144168
statementStart = false;
145-
return;
146-
}
147-
if (declarations) {
148-
return;
169+
return true;
149170
}
150-
if ((statementStart || handlerAction) && (kind == K_IF || kind == K_LOOP
151-
|| keyword(token, "WHILE") || keyword(token, "REPEAT"))) {
152-
Block block = kind == K_IF ? Block.IF
153-
: kind == K_LOOP ? Block.LOOP
154-
: keyword(token, "WHILE") ? Block.WHILE : Block.REPEAT;
171+
return false;
172+
}
173+
174+
private boolean acceptControlFlow(Token token) {
175+
int kind = token.kind;
176+
Block block = controlBlock(token);
177+
if ((statementStart || handlerAction) && block != null) {
155178
blocks.push(block);
156179
bodyStarted = true;
157180
compoundBody = true;
158181
handlerAction = false;
159182
statementKind = kind;
160183
statementStart = block == Block.LOOP || block == Block.REPEAT;
161-
return;
184+
return true;
162185
}
186+
if (acceptOracleLoop(kind)) {
187+
return true;
188+
}
189+
if (isStatementBranch(kind)) {
190+
startStatement();
191+
return true;
192+
}
193+
return false;
194+
}
195+
196+
private boolean acceptOracleLoop(int kind) {
163197
if (kind == K_LOOP && (statementKind == K_FOR || blocks.peek() == Block.WHILE)) {
164198
// Oracle FOR/WHILE ... LOOP shares the same END LOOP boundary.
165199
if (blocks.peek() != Block.WHILE) {
166200
blocks.push(Block.LOOP);
167201
}
168202
startStatement();
169-
return;
203+
return true;
170204
}
171-
if ((kind == K_THEN || kind == K_ELSE) && !blocks.isEmpty()
205+
return false;
206+
}
207+
208+
private boolean isStatementBranch(int kind) {
209+
return (kind == K_THEN || kind == K_ELSE) && !blocks.isEmpty()
172210
&& blocks.peek() != Block.CASE_EXPRESSION
173-
|| kind == K_DO && blocks.peek() == Block.WHILE) {
174-
startStatement();
175-
return;
176-
}
177-
if (previousKind == K_BEGIN && keyword(token, "ATOMIC")) {
211+
|| kind == K_DO && blocks.peek() == Block.WHILE;
212+
}
213+
214+
private void acceptStatementToken(Token token, Token next) {
215+
int kind = token.kind;
216+
if (isStatementPrefix(token, next)) {
178217
return;
179218
}
180-
if (statementStart && (":".equals(next.image) || ":".equals(token.image))) {
181-
return; // A label precedes the statement it names.
182-
}
183219
if (!bodyStarted) {
184220
// SET may also be a PostgreSQL header option; AS remains recognizable above.
185221
if (!isSimpleStatementStart(kind)) {
@@ -196,6 +232,29 @@ private void acceptTopLevel(Token token, Token next) {
196232
statementStart = false;
197233
}
198234

235+
private boolean isStatementPrefix(Token token, Token next) {
236+
// ATOMIC and a label precede the statement they qualify.
237+
return previousKind == K_BEGIN && keyword(token, "ATOMIC")
238+
|| statementStart && (":".equals(next.image) || ":".equals(token.image));
239+
}
240+
241+
private static boolean isEndQualifier(Token token) {
242+
return token.kind == K_CASE || controlBlock(token) != null;
243+
}
244+
245+
private static Block controlBlock(Token token) {
246+
if (token.kind == K_IF) {
247+
return Block.IF;
248+
}
249+
if (token.kind == K_LOOP) {
250+
return Block.LOOP;
251+
}
252+
if (keyword(token, "WHILE")) {
253+
return Block.WHILE;
254+
}
255+
return keyword(token, "REPEAT") ? Block.REPEAT : null;
256+
}
257+
199258
private void startStatement() {
200259
statementStart = true;
201260
statementKind = -1;

0 commit comments

Comments
 (0)