Source file src/cmd/vendor/golang.org/x/tools/internal/astutil/comment.go

     1  // Copyright 2025 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package astutil
     6  
     7  import (
     8  	"go/ast"
     9  	"go/token"
    10  	"strings"
    11  )
    12  
    13  // Deprecation returns the paragraph of the doc comment that starts with the
    14  // conventional "Deprecation: " marker, as defined by
    15  // https://go.dev/wiki/Deprecated, or "" if the documented symbol is not
    16  // deprecated.
    17  func Deprecation(doc *ast.CommentGroup) string {
    18  	for _, p := range strings.Split(doc.Text(), "\n\n") {
    19  		// There is still some ambiguity for deprecation message. This function
    20  		// only returns the paragraph introduced by "Deprecated: ". More
    21  		// information related to the deprecation may follow in additional
    22  		// paragraphs, but the deprecation message should be able to stand on
    23  		// its own. See golang/go#38743.
    24  		if strings.HasPrefix(p, "Deprecated: ") {
    25  			return p
    26  		}
    27  	}
    28  	return ""
    29  }
    30  
    31  // -- plundered from the future (CL 605517, issue #68021) --
    32  
    33  // TODO(adonovan): replace with ast.Directive after go1.25 (#68021).
    34  // Beware of our local mods to handle analysistest
    35  // "want" comments on the same line.
    36  
    37  // A directive is a comment line with special meaning to the Go
    38  // toolchain or another tool. It has the form:
    39  //
    40  //	//tool:name args
    41  //
    42  // The "tool:" portion is missing for the three directives named
    43  // line, extern, and export.
    44  //
    45  // See https://go.dev/doc/comment#Syntax for details of Go comment
    46  // syntax and https://pkg.go.dev/cmd/compile#hdr-Compiler_Directives
    47  // for details of directives used by the Go compiler.
    48  type Directive struct {
    49  	Pos  token.Pos // of preceding "//"
    50  	Tool string
    51  	Name string
    52  	Args string // may contain internal spaces
    53  }
    54  
    55  // isDirective reports whether c is a comment directive.
    56  // This code is also in go/printer.
    57  func isDirective(c string) bool {
    58  	// "//line " is a line directive.
    59  	// "//extern " is for gccgo.
    60  	// "//export " is for cgo.
    61  	// (The // has been removed.)
    62  	if strings.HasPrefix(c, "line ") || strings.HasPrefix(c, "extern ") || strings.HasPrefix(c, "export ") {
    63  		return true
    64  	}
    65  
    66  	// "//[a-z0-9]+:[a-z0-9]"
    67  	// (The // has been removed.)
    68  	colon := strings.Index(c, ":")
    69  	if colon <= 0 || colon+1 >= len(c) {
    70  		return false
    71  	}
    72  	for i := 0; i <= colon+1; i++ {
    73  		if i == colon {
    74  			continue
    75  		}
    76  		b := c[i]
    77  		if !('a' <= b && b <= 'z' || '0' <= b && b <= '9') {
    78  			return false
    79  		}
    80  	}
    81  	return true
    82  }
    83  
    84  // Directives returns the directives within the comment.
    85  func Directives(g *ast.CommentGroup) (res []*Directive) {
    86  	if g != nil {
    87  		// Avoid (*ast.CommentGroup).Text() as it swallows directives.
    88  		for _, c := range g.List {
    89  			if len(c.Text) > 2 &&
    90  				c.Text[1] == '/' &&
    91  				c.Text[2] != ' ' &&
    92  				isDirective(c.Text[2:]) {
    93  
    94  				tool, nameargs, ok := strings.Cut(c.Text[2:], ":")
    95  				if !ok {
    96  					// Must be one of {line,extern,export}.
    97  					tool, nameargs = "", tool
    98  				}
    99  				name, args, _ := strings.Cut(nameargs, " ") // tab??
   100  				// Permit an additional line comment after the args, chiefly to support
   101  				// [golang.org/x/tools/go/analysis/analysistest].
   102  				args, _, _ = strings.Cut(args, "//")
   103  				res = append(res, &Directive{
   104  					Pos:  c.Slash,
   105  					Tool: tool,
   106  					Name: name,
   107  					Args: strings.TrimSpace(args),
   108  				})
   109  			}
   110  		}
   111  	}
   112  	return
   113  }
   114  

View as plain text