github.com/vanstinator/golangci-lint@v0.0.0-20240223191551-cc572f00d9d1/pkg/golinters/gochecksumtype.go (about) 1 package golinters 2 3 import ( 4 "strings" 5 "sync" 6 7 gochecksumtype "github.com/alecthomas/go-check-sumtype" 8 "golang.org/x/tools/go/analysis" 9 "golang.org/x/tools/go/packages" 10 11 "github.com/vanstinator/golangci-lint/pkg/golinters/goanalysis" 12 "github.com/vanstinator/golangci-lint/pkg/lint/linter" 13 "github.com/vanstinator/golangci-lint/pkg/result" 14 ) 15 16 const goCheckSumTypeName = "gochecksumtype" 17 18 func NewGoCheckSumType() *goanalysis.Linter { 19 var mu sync.Mutex 20 var resIssues []goanalysis.Issue 21 22 analyzer := &analysis.Analyzer{ 23 Name: goCheckSumTypeName, 24 Doc: goanalysis.TheOnlyanalyzerDoc, 25 Run: func(pass *analysis.Pass) (any, error) { 26 issues, err := runGoCheckSumType(pass) 27 if err != nil { 28 return nil, err 29 } 30 31 if len(issues) == 0 { 32 return nil, nil 33 } 34 35 mu.Lock() 36 resIssues = append(resIssues, issues...) 37 mu.Unlock() 38 39 return nil, nil 40 }, 41 } 42 43 return goanalysis.NewLinter( 44 goCheckSumTypeName, 45 `Run exhaustiveness checks on Go "sum types"`, 46 []*analysis.Analyzer{analyzer}, 47 nil, 48 ).WithIssuesReporter(func(ctx *linter.Context) []goanalysis.Issue { 49 return resIssues 50 }).WithLoadMode(goanalysis.LoadModeTypesInfo) 51 } 52 53 func runGoCheckSumType(pass *analysis.Pass) ([]goanalysis.Issue, error) { 54 var resIssues []goanalysis.Issue 55 56 pkg := &packages.Package{ 57 Fset: pass.Fset, 58 Syntax: pass.Files, 59 Types: pass.Pkg, 60 TypesInfo: pass.TypesInfo, 61 } 62 63 var unknownError error 64 errors := gochecksumtype.Run([]*packages.Package{pkg}) 65 for _, err := range errors { 66 err, ok := err.(gochecksumtype.Error) 67 if !ok { 68 unknownError = err 69 continue 70 } 71 72 resIssues = append(resIssues, goanalysis.NewIssue(&result.Issue{ 73 FromLinter: goCheckSumTypeName, 74 Text: strings.TrimPrefix(err.Error(), err.Pos().String()+": "), 75 Pos: err.Pos(), 76 }, pass)) 77 } 78 79 return resIssues, unknownError 80 }