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