feat(format): implement PL/pgSQL body formatting

* add formatBody and formatBodyInner functions for DECLARE section
* update needSpace to handle LBracket correctly
* enhance semanticallyEqual to compare dollar-quoted bodies
* add test data for broken layout scenarios
This commit is contained in:
2026-06-23 21:15:27 +02:00
parent 625ddc79a1
commit 6492ab35b7
7 changed files with 454 additions and 18 deletions
+15 -5
View File
@@ -83,8 +83,9 @@ func TestCorpusIdempotentAndSafe(t *testing.T) {
// semanticallyEqual compares the non-trivia token streams of two sources,
// treating unquoted identifiers/keywords case-insensitively and everything
// else (strings, numbers, dollar bodies, operators, punctuation) exactly. This
// validates that formatting changed only layout/casing, never meaning.
// else (strings, numbers, operators, punctuation) exactly. Dollar-quoted body
// tokens are compared recursively so body whitespace normalization does not
// trigger a false failure.
func semanticallyEqual(a, b string) bool {
ta := significant(a)
tb := significant(b)
@@ -95,12 +96,21 @@ func semanticallyEqual(a, b string) bool {
if ta[i].Kind != tb[i].Kind {
return false
}
if ta[i].Kind == lexer.Ident {
switch ta[i].Kind {
case lexer.Ident:
if !strings.EqualFold(ta[i].Text, tb[i].Text) {
return false
}
} else if ta[i].Text != tb[i].Text {
return false
case lexer.DollarString:
_, innerA, _, okA := splitDollarQuote(ta[i].Text)
_, innerB, _, okB := splitDollarQuote(tb[i].Text)
if okA != okB || (okA && !semanticallyEqual(innerA, innerB)) {
return false
}
default:
if ta[i].Text != tb[i].Text {
return false
}
}
}
return true