Skip to content

Commit 02a465e

Browse files
committed
formatter: avoid blank before sole returns
Do not insert the blank-before-return separator when a return is the only statement in its block. This keeps compact guard clauses from gaining an empty line just because the return call wraps across multiple lines. Preserve the existing separator behavior for leading comments attached to the return. Add a focused regression for the wrapped fmt.Errorf shape seen in adoption diffs.
1 parent e351c61 commit 02a465e

2 files changed

Lines changed: 58 additions & 0 deletions

File tree

dsl/condition.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2113,6 +2113,19 @@ func (c *IsReturnNeedingBlankCond) Eval(caps Captures, ctx *Context) bool {
21132113
if !ok {
21142114
return false
21152115
}
2116+
if block, ok := ctx.Parent(node).(*ast.BlockStmt); ok &&
2117+
block != nil && len(block.List) == 1 && block.List[0] == node {
2118+
2119+
brace := ctx.Fset.Position(block.Lbrace).Offset
2120+
returnStart := ctx.Fset.Position(node.Pos()).Offset
2121+
if brace >= 0 && brace+1 <= returnStart {
2122+
gap := string(ctx.Source[brace+1 : returnStart])
2123+
if !strings.Contains(gap, "//") &&
2124+
!strings.Contains(gap, "/*") {
2125+
return false
2126+
}
2127+
}
2128+
}
21162129

21172130
pos := ctx.Fset.Position(node.Pos())
21182131
nodeStart := pos.Offset

formatter/pipeline_dsl_blanklines_extras_test.go

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,4 +169,49 @@ func record() {}
169169
require.NoError(t, err)
170170
}
171171

172+
func TestDSLBlankLinesNative_DoesNotBlankBeforeOnlyWrappedReturn(t *testing.T) {
173+
const in = `package p
174+
175+
import "fmt"
176+
177+
func f(i int, childIdx uint32) error {
178+
if childIdx <= uint32(i) {
179+
return fmt.Errorf("node[%d] child index "+
180+
"%d must be > parent index (cycle or "+
181+
"back-reference)", i, childIdx)
182+
}
183+
184+
return nil
185+
}
186+
`
187+
188+
p := NewPipeline(
189+
PipelineConfig{
190+
ColumnLimit: 80,
191+
TabStop: 8,
192+
UseDSLLogCalls: true,
193+
UseDSLBlankLines: true,
194+
UseDSLBlankLinesNative: true,
195+
},
196+
)
197+
198+
first := p.Format([]byte(in))
199+
second := p.Format(first)
200+
require.Equal(t, string(first), string(second))
201+
202+
out := string(first)
203+
require.Contains(
204+
t, out,
205+
"if childIdx <= uint32(i) {\n return fmt.Errorf(",
206+
)
207+
require.NotContains(
208+
t, out,
209+
"if childIdx <= uint32(i) {\n\n return fmt.Errorf(",
210+
)
211+
212+
fset := token.NewFileSet()
213+
_, err := parser.ParseFile(fset, "out.go", first, parser.AllErrors)
214+
require.NoError(t, err)
215+
}
216+
172217
// Note: legacy/parity profiles were removed; llformat is next-only.

0 commit comments

Comments
 (0)