src

Go monorepo.
git clone git://code.dwrz.net/src
Log | Files | Refs

st1012.go (1577B)


      1 package st1012
      2 
      3 import (
      4 	"fmt"
      5 	"go/ast"
      6 	"go/token"
      7 	"strings"
      8 
      9 	"honnef.co/go/tools/analysis/code"
     10 	"honnef.co/go/tools/analysis/lint"
     11 	"honnef.co/go/tools/analysis/report"
     12 
     13 	"golang.org/x/tools/go/analysis"
     14 )
     15 
     16 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{
     17 	Analyzer: &analysis.Analyzer{
     18 		Name: "ST1012",
     19 		Run:  run,
     20 	},
     21 	Doc: &lint.RawDocumentation{
     22 		Title: `Poorly chosen name for error variable`,
     23 		Text: `Error variables that are part of an API should be called \'errFoo\' or
     24 \'ErrFoo\'.`,
     25 		Since:   "2019.1",
     26 		MergeIf: lint.MergeIfAny,
     27 	},
     28 })
     29 
     30 var Analyzer = SCAnalyzer.Analyzer
     31 
     32 func run(pass *analysis.Pass) (any, error) {
     33 	for _, f := range pass.Files {
     34 		for _, decl := range f.Decls {
     35 			gen, ok := decl.(*ast.GenDecl)
     36 			if !ok || gen.Tok != token.VAR {
     37 				continue
     38 			}
     39 			for _, spec := range gen.Specs {
     40 				spec := spec.(*ast.ValueSpec)
     41 				if len(spec.Names) != len(spec.Values) {
     42 					continue
     43 				}
     44 
     45 				for i, name := range spec.Names {
     46 					val := spec.Values[i]
     47 					if !code.IsCallToAny(pass, val, "errors.New", "fmt.Errorf") {
     48 						continue
     49 					}
     50 
     51 					if pass.Pkg.Path() == "net/http" && strings.HasPrefix(name.Name, "http2err") {
     52 						// special case for internal variable names of
     53 						// bundled HTTP 2 code in net/http
     54 						continue
     55 					}
     56 					prefix := "err"
     57 					if name.IsExported() {
     58 						prefix = "Err"
     59 					}
     60 					if !strings.HasPrefix(name.Name, prefix) {
     61 						report.Report(pass, name, fmt.Sprintf("error var %s should have name of the form %sFoo", name.Name, prefix))
     62 					}
     63 				}
     64 			}
     65 		}
     66 	}
     67 	return nil, nil
     68 }