github.com/machinefi/w3bstream@v1.6.5-rc9.0.20240426031326-b8c7c4876e72/pkg/depends/x/pkgx/pkgx_comment.go (about)

     1  package pkgx
     2  
     3  import (
     4  	"go/ast"
     5  	"go/token"
     6  	"sort"
     7  )
     8  
     9  type CommentScanner struct {
    10  	*ast.File
    11  	ast.CommentMap
    12  }
    13  
    14  func NewCommentScanner(fs *token.FileSet, f *ast.File) *CommentScanner {
    15  	return &CommentScanner{
    16  		File:       f,
    17  		CommentMap: ast.NewCommentMap(fs, f, f.Comments),
    18  	}
    19  }
    20  
    21  func (c *CommentScanner) CommentsOf(n ast.Node) string {
    22  	return StringifyCommentGroup(c.CommentGroupsOf(n)...)
    23  }
    24  
    25  func (c *CommentScanner) CommentGroupsOf(n ast.Node) (cgs []*ast.CommentGroup) {
    26  	if n == nil {
    27  		return
    28  	}
    29  
    30  	switch n.(type) {
    31  	case *ast.File, *ast.Field, ast.Stmt, ast.Decl:
    32  		if comments, ok := c.CommentMap[n]; ok {
    33  			cgs = comments
    34  		}
    35  	case ast.Spec:
    36  		if comments, ok := c.CommentMap[n]; ok {
    37  			cgs = append(cgs, comments...)
    38  		}
    39  		if len(cgs) == 0 {
    40  			for node, comments := range c.CommentMap {
    41  				if decl, ok := node.(*ast.GenDecl); ok {
    42  					for _, spec := range decl.Specs {
    43  						if n == spec {
    44  							cgs = append(cgs, comments...)
    45  						}
    46  					}
    47  				}
    48  			}
    49  		}
    50  	default:
    51  		var (
    52  			pos    token.Pos = -1
    53  			parent ast.Node
    54  		)
    55  		ast.Inspect(c.File, func(node ast.Node) bool {
    56  			switch node.(type) {
    57  			case *ast.Field, ast.Stmt, ast.Decl, ast.Spec:
    58  				if n.Pos() >= node.Pos() && n.End() <= node.End() {
    59  					next := n.Pos() - node.Pos()
    60  					if pos == -1 || next <= pos {
    61  						pos, parent = next, node
    62  					}
    63  				}
    64  			}
    65  			return true
    66  		})
    67  		if parent != nil {
    68  			cgs = c.CommentGroupsOf(parent)
    69  		}
    70  	}
    71  	sort.Slice(cgs, func(i, j int) bool {
    72  		return cgs[i].Pos() < cgs[j].Pos()
    73  	})
    74  	return
    75  }