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