sa5004.go (1363B)
1 package sa5004 2 3 import ( 4 "go/ast" 5 6 "honnef.co/go/tools/analysis/code" 7 "honnef.co/go/tools/analysis/edit" 8 "honnef.co/go/tools/analysis/lint" 9 "honnef.co/go/tools/analysis/report" 10 "honnef.co/go/tools/pattern" 11 12 "golang.org/x/tools/go/analysis" 13 ) 14 15 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ 16 Analyzer: &analysis.Analyzer{ 17 Name: "SA5004", 18 Run: run, 19 Requires: code.RequiredAnalyzers, 20 }, 21 Doc: &lint.RawDocumentation{ 22 Title: `\"for { select { ...\" with an empty default branch spins`, 23 Since: "2017.1", 24 Severity: lint.SeverityWarning, 25 MergeIf: lint.MergeIfAny, 26 }, 27 }) 28 29 var Analyzer = SCAnalyzer.Analyzer 30 31 var query = pattern.MustParse(`(ForStmt nil nil nil (SelectStmt body))`) 32 33 func run(pass *analysis.Pass) (any, error) { 34 for _, m := range code.Matches(pass, query) { 35 for _, c := range m.State["body"].([]ast.Stmt) { 36 // FIXME this leaves behind an empty line, and possibly 37 // comments in the default branch. We can't easily fix 38 // either. 39 if comm, ok := c.(*ast.CommClause); ok && comm.Comm == nil && len(comm.Body) == 0 { 40 report.Report(pass, comm, 41 "should not have an empty default case in a for+select loop; the loop will spin", 42 report.Fixes(edit.Fix("Remove empty default branch", edit.Delete(comm)))) 43 // there can only be one default case 44 break 45 } 46 } 47 } 48 return nil, nil 49 }