github.com/nozzle/golangci-lint@v1.49.0-nz3/pkg/golinters/gocognit.go (about) 1 package golinters 2 3 import ( 4 "fmt" 5 "sort" 6 "sync" 7 8 "github.com/uudashr/gocognit" 9 "golang.org/x/tools/go/analysis" 10 11 "github.com/golangci/golangci-lint/pkg/config" 12 "github.com/golangci/golangci-lint/pkg/golinters/goanalysis" 13 "github.com/golangci/golangci-lint/pkg/lint/linter" 14 "github.com/golangci/golangci-lint/pkg/result" 15 ) 16 17 const gocognitName = "gocognit" 18 19 //nolint:dupl 20 func NewGocognit(settings *config.GocognitSettings) *goanalysis.Linter { 21 var mu sync.Mutex 22 var resIssues []goanalysis.Issue 23 24 analyzer := &analysis.Analyzer{ 25 Name: goanalysis.TheOnlyAnalyzerName, 26 Doc: goanalysis.TheOnlyanalyzerDoc, 27 Run: func(pass *analysis.Pass) (interface{}, error) { 28 issues := runGocognit(pass, settings) 29 30 if len(issues) == 0 { 31 return nil, nil 32 } 33 34 mu.Lock() 35 resIssues = append(resIssues, issues...) 36 mu.Unlock() 37 38 return nil, nil 39 }, 40 } 41 42 return goanalysis.NewLinter( 43 gocognitName, 44 "Computes and checks the cognitive complexity of functions", 45 []*analysis.Analyzer{analyzer}, 46 nil, 47 ).WithIssuesReporter(func(*linter.Context) []goanalysis.Issue { 48 return resIssues 49 }).WithLoadMode(goanalysis.LoadModeSyntax) 50 } 51 52 func runGocognit(pass *analysis.Pass, settings *config.GocognitSettings) []goanalysis.Issue { 53 var stats []gocognit.Stat 54 for _, f := range pass.Files { 55 stats = gocognit.ComplexityStats(f, pass.Fset, stats) 56 } 57 if len(stats) == 0 { 58 return nil 59 } 60 61 sort.SliceStable(stats, func(i, j int) bool { 62 return stats[i].Complexity > stats[j].Complexity 63 }) 64 65 issues := make([]goanalysis.Issue, 0, len(stats)) 66 for _, s := range stats { 67 if s.Complexity <= settings.MinComplexity { 68 break // Break as the stats is already sorted from greatest to least 69 } 70 71 issues = append(issues, goanalysis.NewIssue(&result.Issue{ 72 Pos: s.Pos, 73 Text: fmt.Sprintf("cognitive complexity %d of func %s is high (> %d)", 74 s.Complexity, formatCode(s.FuncName, nil), settings.MinComplexity), 75 FromLinter: gocognitName, 76 }, pass)) 77 } 78 79 return issues 80 }