github.com/jmigpin/editor@v1.6.0/core/godebug/comments.go (about)

     1  package godebug
     2  
     3  import (
     4  	"go/ast"
     5  	"go/token"
     6  	"sort"
     7  )
     8  
     9  // https://github.com/golang/go/issues/20744
    10  
    11  // Comment nodes mapped to the following relevant node. Used for godebug directives.
    12  func commentsWithNodes(fset *token.FileSet, topNode ast.Node, cgs []*ast.CommentGroup) (res []*CommentWithNode) {
    13  
    14  	// ensure it is sorted (sanity check)
    15  	sort.Slice(cgs, func(a, b int) bool {
    16  		return cgs[a].Pos() < cgs[b].Pos()
    17  	})
    18  
    19  	k := -1
    20  	next := func() *ast.CommentGroup {
    21  		k++
    22  		if k < len(cgs) {
    23  			return cgs[k]
    24  		}
    25  		return nil
    26  	}
    27  	cur := next() // current
    28  	ast.Inspect(topNode, func(n ast.Node) bool {
    29  		if cur == nil {
    30  			return false
    31  		}
    32  		n2 := (ast.Node)(nil)
    33  		switch n.(type) {
    34  		case ast.Stmt, ast.Decl, ast.Spec: // relevant node
    35  			n2 = n
    36  		}
    37  		if n2 == nil {
    38  			return true
    39  		}
    40  		// catch first node after the comment
    41  		for n2.Pos() > cur.Pos() {
    42  			for _, c := range cur.List {
    43  				u := &CommentWithNode{c, n2}
    44  				res = append(res, u)
    45  			}
    46  			cur = next()
    47  			if cur == nil {
    48  				break
    49  			}
    50  		}
    51  		return true
    52  	})
    53  	return res
    54  }
    55  
    56  type CommentWithNode struct {
    57  	Comment *ast.Comment
    58  	Node    ast.Node
    59  }
    60  
    61  //----------
    62  
    63  //func annOptNodesMap2(fset *token.FileSet, astFile *ast.File, opts []*AnnotationOpt) map[*AnnotationOpt]ast.Node {
    64  //	m := map[*AnnotationOpt]ast.Node{}
    65  //	if len(opts) == 0 {
    66  //		return m
    67  //	}
    68  
    69  //	sort.Slice(opts, func(a, b int) bool {
    70  //		return opts[a].Comment.Pos() < opts[b].Comment.Pos()
    71  //	})
    72  
    73  //	k := -1
    74  //	nextOpt := func() *AnnotationOpt {
    75  //		k++
    76  //		if k < len(opts) {
    77  //			return opts[k]
    78  //		}
    79  //		return nil
    80  //	}
    81  //	cur := nextOpt() // current
    82  //	ast.Inspect(astFile, func(n ast.Node) bool {
    83  //		// catch first node after the comment
    84  
    85  //		if cur == nil {
    86  //			return false
    87  //		}
    88  //		n2 := (ast.Node)(nil)
    89  //		switch n.(type) {
    90  //		case ast.Stmt, ast.Decl, ast.Spec:
    91  //			n2 = n
    92  //		}
    93  //		if n2 != nil {
    94  //			if n2.Pos() > cur.Comment.Pos() {
    95  //				m[cur] = n2
    96  //				cur.Node = n2
    97  //				cur = nextOpt()
    98  //			}
    99  //		}
   100  //		return true
   101  //	})
   102  
   103  //	// fill rest of nodes with astfile
   104  //	for ; cur != nil; cur = nextOpt() {
   105  //		m[cur] = astFile
   106  //		cur.Node = astFile
   107  //	}
   108  
   109  //	return m
   110  //}
   111  
   112  //----------
   113  
   114  //// commented: attaches to previous comments
   115  //func annOptNodesMap1(fset *token.FileSet, astFile *ast.File, opts []*AnnotationOpt) map[*AnnotationOpt]ast.Node {
   116  //	// wrap comments in commentgroups to use ast.NewCommentMap
   117  //	cgs := []*ast.CommentGroup{}
   118  //	cmap := map[*ast.CommentGroup]*AnnotationOpt{}
   119  //	for _, opt := range opts {
   120  //		cg := &ast.CommentGroup{List: []*ast.Comment{opt.Comment}}
   121  //		cgs = append(cgs, cg)
   122  //		cmap[cg] = opt
   123  //	}
   124  //	// map annotations to nodes
   125  //	nmap := ast.NewCommentMap(fset, astFile, cgs)
   126  //	optm := map[*AnnotationOpt]ast.Node{}
   127  //	for n, cgs := range nmap {
   128  //		cg := cgs[0]
   129  //		opt, ok := cmap[cg]
   130  //		if ok {
   131  //			opt.Node = n
   132  //			optm[opt] = n
   133  //		}
   134  //	}
   135  //	// annotations that have no node, will have astFile as node
   136  //	for opt := range optm {
   137  //		if opt.Node == nil {
   138  //			opt.Node = astFile
   139  //			optm[opt] = astFile
   140  //		}
   141  //	}
   142  //	return optm
   143  //}