github.com/elek/golangci-lint@v1.42.2-0.20211208090441-c05b7fcb3a9a/pkg/golinters/gochecknoinits.go (about) 1 package golinters 2 3 import ( 4 "fmt" 5 "go/ast" 6 "go/token" 7 "sync" 8 9 "golang.org/x/tools/go/analysis" 10 11 "github.com/elek/golangci-lint/pkg/golinters/goanalysis" 12 "github.com/elek/golangci-lint/pkg/lint/linter" 13 "github.com/elek/golangci-lint/pkg/result" 14 ) 15 16 const gochecknoinitsName = "gochecknoinits" 17 18 func NewGochecknoinits() *goanalysis.Linter { 19 var mu sync.Mutex 20 var resIssues []goanalysis.Issue 21 22 analyzer := &analysis.Analyzer{ 23 Name: gochecknoinitsName, 24 Doc: goanalysis.TheOnlyanalyzerDoc, 25 Run: func(pass *analysis.Pass) (interface{}, error) { 26 var res []goanalysis.Issue 27 for _, file := range pass.Files { 28 fileIssues := checkFileForInits(file, pass.Fset) 29 for i := range fileIssues { 30 res = append(res, goanalysis.NewIssue(&fileIssues[i], pass)) 31 } 32 } 33 if len(res) == 0 { 34 return nil, nil 35 } 36 37 mu.Lock() 38 resIssues = append(resIssues, res...) 39 mu.Unlock() 40 41 return nil, nil 42 }, 43 } 44 return goanalysis.NewLinter( 45 gochecknoinitsName, 46 "Checks that no init functions are present in Go code", 47 []*analysis.Analyzer{analyzer}, 48 nil, 49 ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { 50 return resIssues 51 }).WithLoadMode(goanalysis.LoadModeSyntax) 52 } 53 54 func checkFileForInits(f *ast.File, fset *token.FileSet) []result.Issue { 55 var res []result.Issue 56 for _, decl := range f.Decls { 57 funcDecl, ok := decl.(*ast.FuncDecl) 58 if !ok { 59 continue 60 } 61 62 name := funcDecl.Name.Name 63 if name == "init" && funcDecl.Recv.NumFields() == 0 { 64 res = append(res, result.Issue{ 65 Pos: fset.Position(funcDecl.Pos()), 66 Text: fmt.Sprintf("don't use %s function", formatCode(name, nil)), 67 FromLinter: gochecknoinitsName, 68 }) 69 } 70 } 71 72 return res 73 }