72 lines
2.0 KiB
Go
72 lines
2.0 KiB
Go
// Copyright 2025 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package astutil
|
|
|
|
import (
|
|
"go/ast"
|
|
"go/token"
|
|
"iter"
|
|
"sort"
|
|
"strings"
|
|
)
|
|
|
|
// Deprecation returns the paragraph of the doc comment that starts with the
|
|
// conventional "Deprecation: " marker, as defined by
|
|
// https://go.dev/wiki/Deprecated, or "" if the documented symbol is not
|
|
// deprecated.
|
|
func Deprecation(doc *ast.CommentGroup) string {
|
|
for p := range strings.SplitSeq(doc.Text(), "\n\n") {
|
|
// There is still some ambiguity for deprecation message. This function
|
|
// only returns the paragraph introduced by "Deprecated: ". More
|
|
// information related to the deprecation may follow in additional
|
|
// paragraphs, but the deprecation message should be able to stand on
|
|
// its own. See golang/go#38743.
|
|
if strings.HasPrefix(p, "Deprecated: ") {
|
|
return p
|
|
}
|
|
}
|
|
return ""
|
|
}
|
|
|
|
func Directives(g *ast.CommentGroup) (res []ast.Directive) {
|
|
if g != nil {
|
|
// Avoid (*ast.CommentGroup).Text() as it swallows directives.
|
|
for _, c := range g.List {
|
|
if d, ok := ast.ParseDirective(c.Slash, c.Text); ok {
|
|
res = append(res, d)
|
|
}
|
|
}
|
|
}
|
|
return
|
|
}
|
|
|
|
// Comments returns an iterator over the comments overlapping the specified interval.
|
|
// Comments are sorted by position in the file, so we can use binary search.
|
|
func Comments(file *ast.File, start, end token.Pos) iter.Seq[*ast.Comment] {
|
|
return func(yield func(*ast.Comment) bool) {
|
|
// Find the first comment group that overlaps the range.
|
|
i := sort.Search(len(file.Comments), func(i int) bool {
|
|
return file.Comments[i].End() >= start
|
|
})
|
|
for _, cg := range file.Comments[i:] {
|
|
if cg.Pos() > end {
|
|
return
|
|
}
|
|
// Find the first comment in the group that overlaps the range.
|
|
j := sort.Search(len(cg.List), func(j int) bool {
|
|
return cg.List[j].End() >= start
|
|
})
|
|
for _, co := range cg.List[j:] {
|
|
if co.Pos() > end {
|
|
return
|
|
}
|
|
if !yield(co) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|