Proposal Details
Working with go/ast and comments is hard (inserting/moving comments), but the current API of go/ast does not even make it easy to inspect comments between ast.Nodes. I have defined and seen some sort of Comments function to solve that. Maybe it would be worth adding it directly into go/ast? Additionally none of these implementations that i have seen use binary search to speed this up (EDIT: gofumpt does), we could do that safely here (CL 704255).
I propose:
// CommentsBetween returns a slice of CommentGroups that fully
// reside between start and end.
//
// The returned slice shares the backing array with f.Comments (after slices.Clip).
func CommentsBetween(f *File, start, end token.Pos) []*CommentGroup
or
// CommentsBetween returns an iterator, that yields all CommentGroups that
// fully reside between start and end.
func CommentsBetween(f *File, start, end token.Pos) iter.Seq[*CommentGroup]
By "fully reside," I mean that if start or end falls in the middle of a CommentGroup, that comment is not included.
The benefit of the first variant is that it makes it easy to check for presence: len(CommentsBetween(f, start, end)) != 0, whereas the iterator variant requires more typing: len(slices.Collect(CommentsBetween(f, start, end)) != 0 and is less performant (allocates).
Some code samples that might benefit from such API:
https://github.com/golang/tools/blob/cb57b4c286444e6dbb13514e73962503f5afcf04/internal/analysisinternal/analysis.go#L618-L637
|
for i, g := range f.Comments { |
|
if g.End() >= end { |
|
break |
|
} |
|
// g.End() < end |
|
if beg <= g.Pos() { |
|
// comment is within the range [beg, end[ of import declarations |
|
if i < first { |
|
first = i |
|
} |
|
if i > last { |
|
last = i |
|
} |
|
} |
|
} |
|
|
|
var comments []*CommentGroup |
|
if last >= 0 { |
|
comments = f.Comments[first : last+1] |
|
} |
https://github.com/mvdan/gofumpt/blob/ea1909574445e99958cdcd3416c6bf3a4bb64dfa/format/simplify.go#L161-L166
https://github.com/mvdan/gofumpt/blob/ea1909574445e99958cdcd3416c6bf3a4bb64dfa/format/format.go#L199-L210
Proposal Details
Working with
go/astand comments is hard (inserting/moving comments), but the current API ofgo/astdoes not even make it easy to inspect comments betweenast.Nodes. I have defined and seen some sort ofCommentsfunction to solve that. Maybe it would be worth adding it directly intogo/ast? Additionally none of these implementations that i have seen use binary search to speed this up (EDIT: gofumpt does), we could do that safely here (CL 704255).I propose:
or
By "fully reside," I mean that if
startorendfalls in the middle of aCommentGroup, that comment is not included.The benefit of the first variant is that it makes it easy to check for presence:
len(CommentsBetween(f, start, end)) != 0, whereas the iterator variant requires more typing:len(slices.Collect(CommentsBetween(f, start, end)) != 0and is less performant (allocates).Some code samples that might benefit from such API:
https://github.com/golang/tools/blob/cb57b4c286444e6dbb13514e73962503f5afcf04/internal/analysisinternal/analysis.go#L618-L637
go/src/go/ast/import.go
Lines 140 to 159 in 7f6ff5e
https://github.com/mvdan/gofumpt/blob/ea1909574445e99958cdcd3416c6bf3a4bb64dfa/format/simplify.go#L161-L166
https://github.com/mvdan/gofumpt/blob/ea1909574445e99958cdcd3416c6bf3a4bb64dfa/format/format.go#L199-L210