sa9009.go raw
1 package sa9009
2
3 import (
4 "fmt"
5 "strings"
6
7 "golang.org/x/tools/go/analysis"
8
9 "honnef.co/go/tools/analysis/lint"
10 "honnef.co/go/tools/analysis/report"
11 )
12
13 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
14 Analyzer: &analysis.Analyzer{
15 Name: "SA9009",
16 Run: run,
17 Requires: []*analysis.Analyzer{},
18 },
19 Doc: &lint.RawDocumentation{
20 Title: "Ineffectual Go compiler directive",
21 Text: `
22 A potential Go compiler directive was found, but is ineffectual as it begins
23 with whitespace.`,
24 Since: "2024.1",
25 Severity: lint.SeverityWarning,
26 },
27 })
28
29 var Analyzer = SCAnalyzer.Analyzer
30
31 func run(pass *analysis.Pass) (any, error) {
32 for _, f := range pass.Files {
33 for _, cg := range f.Comments {
34 for _, c := range cg.List {
35 // Compiler directives have to be // comments
36 if !strings.HasPrefix(c.Text, "//") {
37 continue
38 }
39 if pass.Fset.PositionFor(c.Pos(), false).Column != 1 {
40 // Compiler directives have to be top-level. This also
41 // avoids a false positive for
42 // 'import _ "unsafe" // go:linkname'
43 continue
44 }
45 text := strings.TrimLeft(c.Text[2:], " \t")
46 if len(text) == len(c.Text[2:]) {
47 // There was no leading whitespace
48 continue
49 }
50 if !strings.HasPrefix(text, "go:") {
51 // Not an attempted compiler directive
52 continue
53 }
54 text = text[3:]
55 if len(text) == 0 || text[0] < 'a' || text[0] > 'z' {
56 // A letter other than a-z after "go:", so unlikely to be an
57 // attempted compiler directive
58 continue
59 }
60 report.Report(pass, c,
61 fmt.Sprintf(
62 "ineffectual compiler directive due to extraneous space: %q",
63 c.Text))
64 }
65 }
66 }
67 return nil, nil
68 }
69