github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/staticcheck/sa5004/sa5004.go (about) 1 package sa5004 2 3 import ( 4 "go/ast" 5 6 "github.com/amarpal/go-tools/analysis/code" 7 "github.com/amarpal/go-tools/analysis/edit" 8 "github.com/amarpal/go-tools/analysis/lint" 9 "github.com/amarpal/go-tools/analysis/report" 10 11 "golang.org/x/tools/go/analysis" 12 "golang.org/x/tools/go/analysis/passes/inspect" 13 ) 14 15 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ 16 Analyzer: &analysis.Analyzer{ 17 Name: "SA5004", 18 Run: run, 19 Requires: []*analysis.Analyzer{inspect.Analyzer}, 20 }, 21 Doc: &lint.Documentation{ 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 func run(pass *analysis.Pass) (interface{}, error) { 32 fn := func(node ast.Node) { 33 loop := node.(*ast.ForStmt) 34 if len(loop.Body.List) != 1 || loop.Cond != nil || loop.Init != nil { 35 return 36 } 37 sel, ok := loop.Body.List[0].(*ast.SelectStmt) 38 if !ok { 39 return 40 } 41 for _, c := range sel.Body.List { 42 // FIXME this leaves behind an empty line, and possibly 43 // comments in the default branch. We can't easily fix 44 // either. 45 if comm, ok := c.(*ast.CommClause); ok && comm.Comm == nil && len(comm.Body) == 0 { 46 report.Report(pass, comm, "should not have an empty default case in a for+select loop; the loop will spin", 47 report.Fixes(edit.Fix("remove empty default branch", edit.Delete(comm)))) 48 // there can only be one default case 49 break 50 } 51 } 52 } 53 code.Preorder(pass, fn, (*ast.ForStmt)(nil)) 54 return nil, nil 55 }