Skip to content

Commit 0e5ef64

Browse files
flimzymvdan
authored andcommitted
Track parent function declarations/literals rather than relying on astutil.PathEnclosingInterval
1 parent 9203c06 commit 0e5ef64

File tree

1 file changed

+21
-3
lines changed

1 file changed

+21
-3
lines changed

format/format.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,11 @@ type fumpter struct {
185185
blockLevel int
186186

187187
minSplitFactor float64
188+
189+
// parentFuncs is a stack of parent function declarations or
190+
// literals, used to determine return type information when clothing
191+
// naked returns.
192+
parentFuncs []ast.Node
188193
}
189194

190195
func (f *fumpter) commentsBetween(p1, p2 token.Pos) []*ast.CommentGroup {
@@ -319,6 +324,16 @@ var rxCommentDirective = regexp.MustCompile(`^([a-z-]+:[a-z]+|line\b|export\b|ex
319324
func (f *fumpter) applyPre(c *astutil.Cursor) {
320325
f.splitLongLine(c)
321326

327+
if c.Node() != nil && len(f.parentFuncs) > 0 {
328+
// "pop" the last parent if it's no longer valid.
329+
for i := len(f.parentFuncs) - 1; i >= 0; i-- {
330+
if f.parentFuncs[i].End() < c.Node().Pos() {
331+
f.parentFuncs = f.parentFuncs[:i]
332+
break
333+
}
334+
}
335+
}
336+
322337
switch node := c.Node().(type) {
323338
case *ast.File:
324339
// Join contiguous lone var/const/import lines.
@@ -686,19 +701,22 @@ func (f *fumpter) applyPre(c *astutil.Cursor) {
686701
// Only remove lines between the assignment token and the first right-hand side expression
687702
f.removeLines(f.Line(node.TokPos), f.Line(node.Rhs[0].Pos()))
688703

704+
case *ast.FuncDecl, *ast.FuncLit:
705+
// Track the current function declaration or literal, to access
706+
// return type information for clothing of naked returns.
707+
f.parentFuncs = append(f.parentFuncs, node)
689708
// Clothe naked returns
690709
case *ast.ReturnStmt:
691710
if node.Results != nil {
692711
break
693712
}
694713

695714
// We have either a naked return, or a function with no return values
696-
parents, _ := astutil.PathEnclosingInterval(f.astFile, node.Pos(), node.End())
697715
var results *ast.FieldList
698716
// Find the nearest ancestor that is either a func declaration or func literal
699717
parentLoop:
700-
for _, parent := range parents {
701-
switch p := parent.(type) {
718+
for i := len(f.parentFuncs) - 1; i >= 0; i-- {
719+
switch p := f.parentFuncs[i].(type) {
702720
case *ast.FuncDecl:
703721
results = p.Type.Results
704722
break parentLoop

0 commit comments

Comments
 (0)