Skip to content

Commit 192ed9d

Browse files
authored
Merge pull request #111 from mvorisek/fix_end_for_non_case
Fix unopened END indent opened by BEGIN
2 parents a5ae935 + b2df04b commit 192ed9d

7 files changed

+201
-57
lines changed

src/SqlFormatter.php

+37-27
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
use function array_shift;
1616
use function array_unshift;
1717
use function assert;
18-
use function current;
1918
use function in_array;
2019
use function preg_replace;
2120
use function reset;
@@ -24,6 +23,7 @@
2423
use function str_replace;
2524
use function strlen;
2625
use function strtoupper;
26+
use function substr;
2727
use function trim;
2828

2929
use const PHP_SAPI;
@@ -68,6 +68,25 @@ public function format(string $string, string $indentString = ' '): string
6868
$inlineIndented = false;
6969
$clauseLimit = false;
7070

71+
$appendNewLineIfNotAddedFx = static function () use (&$addedNewline, &$return, $tab, &$indentLevel): void {
72+
// Add a newline if not already added
73+
if ($addedNewline) { // @phpstan-ignore if.alwaysFalse
74+
return;
75+
}
76+
77+
$return = rtrim($return, ' ' . $tab);
78+
$return .= "\n" . str_repeat($tab, $indentLevel);
79+
};
80+
$redoIndentationFx = static function () use (&$return, $tab, &$indentLevel): void {
81+
// Redo the indentation since it may be different now
82+
$lastPossiblyIndentLine = substr($return, -($indentLevel + 2));
83+
if (rtrim($lastPossiblyIndentLine, $tab) !== "\n") {
84+
return;
85+
}
86+
87+
$return = substr($return, 0, -($indentLevel + 1)) . str_repeat($tab, $indentLevel);
88+
};
89+
7190
// Tokenize String
7291
$cursor = $this->tokenizer->tokenize($string);
7392

@@ -106,7 +125,7 @@ public function format(string $string, string $indentString = ' '): string
106125
if ($token->isOfType(Token::TOKEN_TYPE_COMMENT, Token::TOKEN_TYPE_BLOCK_COMMENT)) {
107126
if ($token->isOfType(Token::TOKEN_TYPE_BLOCK_COMMENT)) {
108127
$indent = str_repeat($tab, $indentLevel);
109-
$return = rtrim($return, " \t");
128+
$return = rtrim($return, ' ' . $tab);
110129
$return .= "\n" . $indent;
111130
$highlighted = str_replace("\n", "\n" . $indent, $highlighted);
112131
}
@@ -227,31 +246,22 @@ public function format(string $string, string $indentString = ' '): string
227246
continue;
228247
}
229248

230-
// Add a newline before the closing parentheses (if not already added)
231-
if (! $addedNewline) {
232-
$return .= "\n" . str_repeat($tab, $indentLevel);
233-
}
249+
$appendNewLineIfNotAddedFx();
234250
} elseif ($token->isOfType(Token::TOKEN_TYPE_RESERVED_TOPLEVEL)) {
235251
// Top level reserved words start a new line and increase the special indent level
236252
$increaseSpecialIndent = true;
237253

238254
// If the last indent type was special, decrease the special indent for this round
239-
reset($indentTypes);
240-
if (current($indentTypes) === self::INDENT_TYPE_SPECIAL) {
255+
if (reset($indentTypes) === self::INDENT_TYPE_SPECIAL) {
241256
$indentLevel--;
242257
array_shift($indentTypes);
258+
$redoIndentationFx();
243259
}
244260

245261
// Add a newline after the top level reserved word
246262
$newline = true;
247-
// Add a newline before the top level reserved word (if not already added)
248-
if (! $addedNewline) {
249-
$return = rtrim($return, ' ');
250-
$return .= "\n" . str_repeat($tab, $indentLevel);
251-
} else {
252-
// If we already added a newline, redo the indentation since it may be different now
253-
$return = rtrim($return, $tab) . str_repeat($tab, $indentLevel);
254-
}
263+
264+
$appendNewLineIfNotAddedFx();
255265

256266
if ($token->hasExtraWhitespace()) {
257267
$highlighted = preg_replace('/\s+/', ' ', $highlighted);
@@ -263,24 +273,27 @@ public function format(string $string, string $indentString = ' '): string
263273
}
264274
} elseif ($token->value() === ';') {
265275
// If the last indent type was special, decrease the special indent for this round
266-
reset($indentTypes);
267-
if (current($indentTypes) === self::INDENT_TYPE_SPECIAL) {
276+
if (reset($indentTypes) === self::INDENT_TYPE_SPECIAL) {
268277
$indentLevel--;
269278
array_shift($indentTypes);
279+
$redoIndentationFx();
270280
}
271281

272282
$newline = true;
273283
} elseif (strtoupper($token->value()) === 'CASE') {
274284
$increaseBlockIndent = true;
285+
} elseif (strtoupper($token->value()) === 'BEGIN') {
286+
$newline = true;
287+
$increaseBlockIndent = true;
275288
} elseif (in_array(strtoupper($token->value()), ['WHEN', 'THEN', 'ELSE', 'END'], true)) {
276289
if (strtoupper($token->value()) !== 'THEN') {
277290
array_shift($indentTypes);
278291
$indentLevel--;
292+
$redoIndentationFx();
279293

280294
$prevNotWhitespaceToken = $cursor->subCursor()->previous(Token::TOKEN_TYPE_WHITESPACE);
281295
if ($prevNotWhitespaceToken !== null && strtoupper($prevNotWhitespaceToken->value()) !== 'CASE') {
282-
$return = rtrim($return, ' ');
283-
$return .= "\n" . str_repeat($tab, $indentLevel);
296+
$appendNewLineIfNotAddedFx();
284297
}
285298
}
286299

@@ -306,12 +319,9 @@ public function format(string $string, string $indentString = ' '): string
306319
$newline = true;
307320
}
308321
} elseif ($token->isOfType(Token::TOKEN_TYPE_RESERVED_NEWLINE)) {
309-
// Newline reserved words start a new line
310-
// Add a newline before the reserved word (if not already added)
311-
if (! $addedNewline) {
312-
$return = rtrim($return, ' ');
313-
$return .= "\n" . str_repeat($tab, $indentLevel);
314-
}
322+
// Newline reserved words start a new line
323+
324+
$appendNewLineIfNotAddedFx();
315325

316326
if ($token->hasExtraWhitespace()) {
317327
$highlighted = preg_replace('/\s+/', ' ', $highlighted);
@@ -381,7 +391,7 @@ public function format(string $string, string $indentString = ' '): string
381391
}
382392

383393
// Replace tab characters with the configuration tab character
384-
$return = trim(str_replace("\t", $indentString, $return));
394+
$return = trim(str_replace($tab, $indentString, $return));
385395

386396
return $this->highlighter->output($return);
387397
}

tests/clihighlight.txt

+38-10
Original file line numberDiff line numberDiff line change
@@ -1021,18 +1021,19 @@ MY_NON_TOP_LEVEL_KEYWORD_FX_2();
10211021
1 as x
10221022
);
10231023
MY_NON_TOP_LEVEL_KEYWORD_FX_3();
1024-
BEGIN MY_NON_TOP_LEVEL_KEYWORD_FX_4();
1025-
MY_NON_TOP_LEVEL_KEYWORD_FX_5();
1024+
BEGIN
1025+
MY_NON_TOP_LEVEL_KEYWORD_FX_4();
1026+
MY_NON_TOP_LEVEL_KEYWORD_FX_5();
10261027
END;
10271028
BEGIN
1028-
SELECT
1029-
x
1030-
FROM
1031-
(
1032-
SELECT
1033-
1 as x
1034-
);
1035-
MY_NON_TOP_LEVEL_KEYWORD_FX_6();
1029+
SELECT
1030+
x
1031+
FROM
1032+
(
1033+
SELECT
1034+
1 as x
1035+
);
1036+
MY_NON_TOP_LEVEL_KEYWORD_FX_6();
10361037
END;
10371038
---
10381039
SELECT
@@ -1070,3 +1071,30 @@ MY_NON_TOP_LEVEL_KEYWORD_FX_6();
10701071
name
10711072
FROM
10721073
user
1074+
---
1075+
begin
1076+
try insert into [t] ([name], [int], [float], [null])
1077+
values
1078+
(N 'Ewa', 1, 1.0, null);
1079+
end try begin
1080+
catch if ERROR_NUMBER() = 544 begin
1081+
set
1082+
IDENTITY_INSERT [t] on;
1083+
begin
1084+
try insert into [t] ([name], [int], [float], [null])
1085+
values
1086+
(N 'Ewa', 1, 1.0, null);
1087+
set
1088+
IDENTITY_INSERT [t] off;
1089+
end try begin
1090+
catch
1091+
set
1092+
IDENTITY_INSERT [t] off;
1093+
throw;
1094+
end catch
1095+
end
1096+
else
1097+
begin
1098+
throw;
1099+
end
1100+
end catch

tests/compress.txt

+2
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,5 @@ SELECT 1::text;
9797
MY_NON_TOP_LEVEL_KEYWORD_FX_1(); MY_NON_TOP_LEVEL_KEYWORD_FX_2(); SELECT x FROM (SELECT 1 as x); MY_NON_TOP_LEVEL_KEYWORD_FX_3(); BEGIN MY_NON_TOP_LEVEL_KEYWORD_FX_4(); MY_NON_TOP_LEVEL_KEYWORD_FX_5(); END; BEGIN SELECT x FROM (SELECT 1 as x); MY_NON_TOP_LEVEL_KEYWORD_FX_6(); END;
9898
---
9999
SELECT case when name = 1 then 10 when name = 2 then 20 when name = 3 then case when age > 10 then 30 else 31 end else 40 end AS case1, (SELECT case name when 1 then 10 when 2 then 20 when 3 then case age when 10 then 30 else 31 end else 40 end) case2, name FROM user
100+
---
101+
begin try insert into [t] ([name], [int], [float], [null]) values (N'Ewa', 1, 1.0, null); end try begin catch if ERROR_NUMBER() = 544 begin set IDENTITY_INSERT [t] on; begin try insert into [t] ([name], [int], [float], [null]) values (N'Ewa', 1, 1.0, null); set IDENTITY_INSERT [t] off; end try begin catch set IDENTITY_INSERT [t] off; throw; end catch end else begin throw; end end catch

tests/format-highlight.html

+38-10
Original file line numberDiff line numberDiff line change
@@ -1021,18 +1021,19 @@
10211021
<span style="color: green;">1</span> <span style="font-weight:bold;">as</span> <span style="color: #333;">x</span>
10221022
)<span >;</span>
10231023
<span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_3</span>()<span >;</span>
1024-
<span style="font-weight:bold;">BEGIN</span> <span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_4</span>()<span >;</span>
1025-
<span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_5</span>()<span >;</span>
1024+
<span style="font-weight:bold;">BEGIN</span>
1025+
<span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_4</span>()<span >;</span>
1026+
<span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_5</span>()<span >;</span>
10261027
<span style="font-weight:bold;">END</span><span >;</span>
10271028
<span style="font-weight:bold;">BEGIN</span>
1028-
<span style="font-weight:bold;">SELECT</span>
1029-
<span style="color: #333;">x</span>
1030-
<span style="font-weight:bold;">FROM</span>
1031-
(
1032-
<span style="font-weight:bold;">SELECT</span>
1033-
<span style="color: green;">1</span> <span style="font-weight:bold;">as</span> <span style="color: #333;">x</span>
1034-
)<span >;</span>
1035-
<span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_6</span>()<span >;</span>
1029+
<span style="font-weight:bold;">SELECT</span>
1030+
<span style="color: #333;">x</span>
1031+
<span style="font-weight:bold;">FROM</span>
1032+
(
1033+
<span style="font-weight:bold;">SELECT</span>
1034+
<span style="color: green;">1</span> <span style="font-weight:bold;">as</span> <span style="color: #333;">x</span>
1035+
)<span >;</span>
1036+
<span style="color: #333;">MY_NON_TOP_LEVEL_KEYWORD_FX_6</span>()<span >;</span>
10361037
<span style="font-weight:bold;">END</span><span >;</span></pre>
10371038
---
10381039
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">SELECT</span>
@@ -1070,3 +1071,30 @@
10701071
<span style="color: #333;">name</span>
10711072
<span style="font-weight:bold;">FROM</span>
10721073
<span style="color: #333;">user</span></pre>
1074+
---
1075+
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">begin</span>
1076+
<span style="color: #333;">try</span> <span style="font-weight:bold;">insert</span> <span style="font-weight:bold;">into</span> <span style="color: purple;">[t]</span> (<span style="color: purple;">[name]</span><span >,</span> <span style="color: purple;">[int]</span><span >,</span> <span style="color: purple;">[float]</span><span >,</span> <span style="color: purple;">[null]</span>)
1077+
<span style="font-weight:bold;">values</span>
1078+
(<span style="color: #333;">N</span> <span style="color: blue;">'Ewa'</span><span >,</span> <span style="color: green;">1</span><span >,</span> <span style="color: green;">1.0</span><span >,</span> <span style="font-weight:bold;">null</span>)<span >;</span>
1079+
<span style="font-weight:bold;">end</span> <span style="color: #333;">try</span> <span style="font-weight:bold;">begin</span>
1080+
<span style="color: #333;">catch</span> <span style="font-weight:bold;">if</span> <span style="color: #333;">ERROR_NUMBER</span>() <span >=</span> <span style="color: green;">544</span> <span style="font-weight:bold;">begin</span>
1081+
<span style="font-weight:bold;">set</span>
1082+
<span style="color: #333;">IDENTITY_INSERT</span> <span style="color: purple;">[t]</span> <span style="font-weight:bold;">on</span><span >;</span>
1083+
<span style="font-weight:bold;">begin</span>
1084+
<span style="color: #333;">try</span> <span style="font-weight:bold;">insert</span> <span style="font-weight:bold;">into</span> <span style="color: purple;">[t]</span> (<span style="color: purple;">[name]</span><span >,</span> <span style="color: purple;">[int]</span><span >,</span> <span style="color: purple;">[float]</span><span >,</span> <span style="color: purple;">[null]</span>)
1085+
<span style="font-weight:bold;">values</span>
1086+
(<span style="color: #333;">N</span> <span style="color: blue;">'Ewa'</span><span >,</span> <span style="color: green;">1</span><span >,</span> <span style="color: green;">1.0</span><span >,</span> <span style="font-weight:bold;">null</span>)<span >;</span>
1087+
<span style="font-weight:bold;">set</span>
1088+
<span style="color: #333;">IDENTITY_INSERT</span> <span style="color: purple;">[t]</span> <span style="color: #333;">off</span><span >;</span>
1089+
<span style="font-weight:bold;">end</span> <span style="color: #333;">try</span> <span style="font-weight:bold;">begin</span>
1090+
<span style="color: #333;">catch</span>
1091+
<span style="font-weight:bold;">set</span>
1092+
<span style="color: #333;">IDENTITY_INSERT</span> <span style="color: purple;">[t]</span> <span style="color: #333;">off</span><span >;</span>
1093+
<span style="color: #333;">throw</span><span >;</span>
1094+
<span style="font-weight:bold;">end</span> <span style="color: #333;">catch</span>
1095+
<span style="font-weight:bold;">end</span>
1096+
<span style="font-weight:bold;">else</span>
1097+
<span style="font-weight:bold;">begin</span>
1098+
<span style="color: #333;">throw</span><span >;</span>
1099+
<span style="font-weight:bold;">end</span>
1100+
<span style="font-weight:bold;">end</span> <span style="color: #333;">catch</span></pre>

tests/format.txt

+38-10
Original file line numberDiff line numberDiff line change
@@ -1019,18 +1019,19 @@ FROM
10191019
1 as x
10201020
);
10211021
MY_NON_TOP_LEVEL_KEYWORD_FX_3();
1022-
BEGIN MY_NON_TOP_LEVEL_KEYWORD_FX_4();
1023-
MY_NON_TOP_LEVEL_KEYWORD_FX_5();
1022+
BEGIN
1023+
MY_NON_TOP_LEVEL_KEYWORD_FX_4();
1024+
MY_NON_TOP_LEVEL_KEYWORD_FX_5();
10241025
END;
10251026
BEGIN
1026-
SELECT
1027-
x
1028-
FROM
1029-
(
1030-
SELECT
1031-
1 as x
1032-
);
1033-
MY_NON_TOP_LEVEL_KEYWORD_FX_6();
1027+
SELECT
1028+
x
1029+
FROM
1030+
(
1031+
SELECT
1032+
1 as x
1033+
);
1034+
MY_NON_TOP_LEVEL_KEYWORD_FX_6();
10341035
END;
10351036
---
10361037
SELECT
@@ -1068,3 +1069,30 @@ SELECT
10681069
name
10691070
FROM
10701071
user
1072+
---
1073+
begin
1074+
try insert into [t] ([name], [int], [float], [null])
1075+
values
1076+
(N 'Ewa', 1, 1.0, null);
1077+
end try begin
1078+
catch if ERROR_NUMBER() = 544 begin
1079+
set
1080+
IDENTITY_INSERT [t] on;
1081+
begin
1082+
try insert into [t] ([name], [int], [float], [null])
1083+
values
1084+
(N 'Ewa', 1, 1.0, null);
1085+
set
1086+
IDENTITY_INSERT [t] off;
1087+
end try begin
1088+
catch
1089+
set
1090+
IDENTITY_INSERT [t] off;
1091+
throw;
1092+
end catch
1093+
end
1094+
else
1095+
begin
1096+
throw;
1097+
end
1098+
end catch

tests/highlight.html

+24
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,27 @@
356356
<span style="color: #333;">name</span>
357357
<span style="font-weight:bold;">FROM</span>
358358
<span style="color: #333;">user</span></pre>
359+
---
360+
<pre style="color: black; background-color: white;"><span style="font-weight:bold;">begin</span> <span style="color: #333;">try</span>
361+
<span style="font-weight:bold;">insert</span> <span style="font-weight:bold;">into</span> <span style="color: purple;">[t]</span> (<span style="color: purple;">[name]</span><span >,</span> <span style="color: purple;">[int]</span><span >,</span> <span style="color: purple;">[float]</span><span >,</span> <span style="color: purple;">[null]</span>)
362+
<span style="font-weight:bold;">values</span> (<span style="color: #333;">N</span><span style="color: blue;">'Ewa'</span><span >,</span> <span style="color: green;">1</span><span >,</span> <span style="color: green;">1.0</span><span >,</span> <span style="font-weight:bold;">null</span>)<span >;</span>
363+
<span style="font-weight:bold;">end</span> <span style="color: #333;">try</span>
364+
<span style="font-weight:bold;">begin</span> <span style="color: #333;">catch</span>
365+
<span style="font-weight:bold;">if</span> <span style="color: #333;">ERROR_NUMBER</span>() <span >=</span> <span style="color: green;">544</span>
366+
<span style="font-weight:bold;">begin</span>
367+
<span style="font-weight:bold;">set</span> <span style="color: #333;">IDENTITY_INSERT</span> <span style="color: purple;">[t]</span> <span style="font-weight:bold;">on</span><span >;</span>
368+
<span style="font-weight:bold;">begin</span> <span style="color: #333;">try</span>
369+
<span style="font-weight:bold;">insert</span> <span style="font-weight:bold;">into</span> <span style="color: purple;">[t]</span> (<span style="color: purple;">[name]</span><span >,</span> <span style="color: purple;">[int]</span><span >,</span> <span style="color: purple;">[float]</span><span >,</span> <span style="color: purple;">[null]</span>)
370+
<span style="font-weight:bold;">values</span> (<span style="color: #333;">N</span><span style="color: blue;">'Ewa'</span><span >,</span> <span style="color: green;">1</span><span >,</span> <span style="color: green;">1.0</span><span >,</span> <span style="font-weight:bold;">null</span>)<span >;</span>
371+
<span style="font-weight:bold;">set</span> <span style="color: #333;">IDENTITY_INSERT</span> <span style="color: purple;">[t]</span> <span style="color: #333;">off</span><span >;</span>
372+
<span style="font-weight:bold;">end</span> <span style="color: #333;">try</span>
373+
<span style="font-weight:bold;">begin</span> <span style="color: #333;">catch</span>
374+
<span style="font-weight:bold;">set</span> <span style="color: #333;">IDENTITY_INSERT</span> <span style="color: purple;">[t]</span> <span style="color: #333;">off</span><span >;</span>
375+
<span style="color: #333;">throw</span><span >;</span>
376+
<span style="font-weight:bold;">end</span> <span style="color: #333;">catch</span>
377+
<span style="font-weight:bold;">end</span>
378+
<span style="font-weight:bold;">else</span>
379+
<span style="font-weight:bold;">begin</span>
380+
<span style="color: #333;">throw</span><span >;</span>
381+
<span style="font-weight:bold;">end</span>
382+
<span style="font-weight:bold;">end</span> <span style="color: #333;">catch</span></pre>

tests/sql.sql

+24
Original file line numberDiff line numberDiff line change
@@ -356,3 +356,27 @@ SELECT
356356
name
357357
FROM
358358
user
359+
---
360+
begin try
361+
insert into [t] ([name], [int], [float], [null])
362+
values (N'Ewa', 1, 1.0, null);
363+
end try
364+
begin catch
365+
if ERROR_NUMBER() = 544
366+
begin
367+
set IDENTITY_INSERT [t] on;
368+
begin try
369+
insert into [t] ([name], [int], [float], [null])
370+
values (N'Ewa', 1, 1.0, null);
371+
set IDENTITY_INSERT [t] off;
372+
end try
373+
begin catch
374+
set IDENTITY_INSERT [t] off;
375+
throw;
376+
end catch
377+
end
378+
else
379+
begin
380+
throw;
381+
end
382+
end catch

0 commit comments

Comments
 (0)