github.com/amarpal/go-tools@v0.0.0-20240422043104-40142f59f616/staticcheck/sa1015/sa1015.go (about) 1 package sa1015 2 3 import ( 4 "github.com/amarpal/go-tools/analysis/code" 5 "github.com/amarpal/go-tools/analysis/lint" 6 "github.com/amarpal/go-tools/analysis/report" 7 "github.com/amarpal/go-tools/go/ir" 8 "github.com/amarpal/go-tools/go/ir/irutil" 9 "github.com/amarpal/go-tools/internal/passes/buildir" 10 11 "golang.org/x/tools/go/analysis" 12 ) 13 14 var SCAnalyzer = lint.InitializeAnalyzer(&lint.Analyzer{ 15 Analyzer: &analysis.Analyzer{ 16 Name: "SA1015", 17 Run: run, 18 Requires: []*analysis.Analyzer{buildir.Analyzer}, 19 }, 20 Doc: &lint.Documentation{ 21 Title: `Using \'time.Tick\' in a way that will leak. Consider using \'time.NewTicker\', and only use \'time.Tick\' in tests, commands and endless functions`, 22 Since: "2017.1", 23 Severity: lint.SeverityWarning, 24 MergeIf: lint.MergeIfAny, 25 }, 26 }) 27 28 var Analyzer = SCAnalyzer.Analyzer 29 30 func run(pass *analysis.Pass) (interface{}, error) { 31 for _, fn := range pass.ResultOf[buildir.Analyzer].(*buildir.IR).SrcFuncs { 32 if code.IsMainLike(pass) || code.IsInTest(pass, fn) { 33 continue 34 } 35 for _, block := range fn.Blocks { 36 for _, ins := range block.Instrs { 37 call, ok := ins.(*ir.Call) 38 if !ok || !irutil.IsCallTo(call.Common(), "time.Tick") { 39 continue 40 } 41 if !irutil.Terminates(call.Parent()) { 42 continue 43 } 44 report.Report(pass, call, "using time.Tick leaks the underlying ticker, consider using it only in endless functions, tests and the main package, and use time.NewTicker here") 45 } 46 } 47 } 48 return nil, nil 49 }